2012-03-04 120 views
9

我有兩張表(國家/地區&鴨子),其中國家/地區表具有世界上的每個國家/地區,並且鴨子表具有包含country_id字段以鏈接到主要國家/地區的鴨子列表。MySQL返回連接表的第一行

我試圖找到一個只有至少有一隻鴨子的國家的列表,以及那個國家內最高評分鴨子的鴨子表中的單個匹配記錄。到目前爲止,我有:

SELECT * 
FROM country c 
INNER JOIN ducks d ON c.id = d.country_id 
ORDER BY c.country ASC, d.rating DESC 

這將返回每個鴨子的列表,而不是每個國家只有一個。

如果有人能指出我在這裏正確的方向,我將不勝感激。我寧願在SQL中做這件事,也不願意爲每個國家提供一個單獨的查詢來取出評分最高的鴨子。

+2

請參見:http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax- row-per-group-in-sql /例如如何做到這一點。 – imm 2012-03-04 21:54:46

+0

你想要哪一隻鴨子?只有任何人? – dotoree 2012-03-04 21:56:06

+1

@dotoree最高評分(最高鴨評級從集) – 2012-03-04 22:03:35

回答

19
​​

索引:

+0

謝謝你完美的作品 – 2012-03-04 22:12:48

+0

@ imm's anwer也很好。 – 2012-03-04 22:15:10

+0

+1非常好。有沒有可能實現這個沒有子查詢呢? – 2012-03-04 22:24:00

-1

許多數據庫都有一些等價的「從...中選擇10 *」。在mySql中,語法是「select * from ... limit 10」。

...但是...

在這種情況下,uou真的要 「分組依據」 和 「Max()」!在(country_id, rating, id)

SELECT c.*, d.* 
FROM country c 
INNER JOIN (
    SELECT d.country_id, d.id, MAX(d.rating) AS rating 
    FROM ducks d 
    GROUP BY d.country_id 
) q ON (q.country_id = c.id) 

INNER JOIN ducks d 
    ON (d.country_id, d.rating) = (q.country_id, q.rating) 
+1

嗨,該組通過限制結果,但MAX()函數只顯示該組的最大值,但該行的其餘部分包含數據MySQL發現的第一條記錄,而不是具有最高評分的記錄。這是我到目前爲止:'SELECT c。*,d。*,MAX(d.rating) FROM country c INNER JOIN ducks d ON c.id = d.country_id GROUP BY c.country ORDER BY c.country ASC,d.rating DESC' – 2012-03-04 22:03:37

0

試試這個:

SELECT c.country, MAX(d.rating) AS max_rating 
FROM country c 
JOIN ducks d ON c.id = d.country_id 
GROUP BY c.id 
ORDER BY c.country ASC 

如果 「最高等級」 爲1,則改變MAX(d.rating)MIN(d.rating)

+0

嗨,這是非常接近,因爲它返回一個國家的最大額定值,我試圖還返回對應於該最大額定值的記錄。例如,如果我將代碼的第一行更改爲「SELECT c.country,d.id,d.rating,MAX(d.rating)',那麼d.rating並不總是等於MAX(d.rating),如果這樣做感覺 – 2012-03-04 22:06:48

+0

是的,它的確如此。我已經更新了答案。請再試一次。 – 2012-03-04 22:07:56

+0

@ J.Bruni:'ORDER BY'後面的'HAVING'不是有效的語法。 – 2012-03-04 22:13:10

3

你可以嘗試對於MyISAM表或(country_id, rating)對於InnoDB表,w應該幫忙。

此查詢將顯示每個國家只有一個duck,即使有多個具有相同的評級。如果你想要出現綁定分級的鴨子,請使用@ imm的GROUP BY答案。

+0

這隻需要再多一次連接就可以顯示鴨子的細節:'INNER JOIN ducks d ON(d.country_id,d.rating)=(q.country_id,q.rating)' – 2012-03-04 22:15:33

+0

@ ypercube,真正的dat。 – imm 2012-03-04 22:17:02

8

你可以嘗試只增加一個選擇加入,爲

SELECT c.*, d.* 
FROM country c 
INNER JOIN ducks d ON c.id = d.country_id 
LEFT JOIN ducks d2 ON d.country_id = d2.country_id AND d2.rating > d.rating 
WHERE d2.id IS NULL 
+0

太棒了!我喜歡這個版本。 – 2012-03-04 22:33:59

+1

最好有'SELECT c。*,d。*'。不需要包含'd2。*'列 - 這將全部爲NULL。 – 2012-03-05 08:25:01

+1

這個應該是被接受的答案 – ScottG 2014-06-25 13:23:11