2012-03-04 86 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