给定此数据集:
ID Name City Birthyear 1 Egon Spengler New York 1957 2 Mac Taylor New York 1955 3 Sarah Connor Los Angeles 1959 4 Jean-Luc Picard La Barre 2305 5 Ellen Ripley Nostromo 2092 6 James T. Kirk Riverside 2233 7 Henry Jones Chicago 1899
我需要找到3个最老的人,但是每个城市只有一个。
如果它只是最老的三个,那将是…
但是,由于Egon Spengler和Mac Taylor都位于纽约,因此Egon Spengler会退学,而下一个(Sarah Connor /洛杉矶)会进来。
有什么优雅的解决方案吗?
更新:
当前,PConroy的一种变体是最好/最快的解决方案:
SELECT P.*, COUNT(*) AS ct FROM people P JOIN (SELECT MIN(Birthyear) AS Birthyear FROM people GROUP by City) P2 ON P2.Birthyear = P.Birthyear GROUP BY P.City ORDER BY P.Birthyear ASC LIMIT 10;
对于大数据集(5分钟后中止),他最初的“ IN”查询速度非常慢,但是将子查询移至JOIN可以大大提高速度。大约花费了0.15秒。在我的测试环境中为1 mio行。我有一个关于“城市,出生年”的索引,另一个是关于“出生年”的索引。
注意:这与…有关
可能不是最优雅的解决方案,并且IN在更大的桌子上,其性能可能会受到影响。
IN
嵌套查询获取Birthyear每个城市的最小值。只有具有此Birthyear条件的记录才在外部查询中匹配。按年龄排序,然后限制为3个结果,则可以使您成为所在城市中年龄最大的3个最老的人(Egon Spengler退学。)
Birthyear
SELECT Name, City, Birthyear, COUNT(*) AS ct FROM table WHERE Birthyear IN (SELECT MIN(Birthyear) FROM table GROUP by City) GROUP BY City ORDER BY Birthyear DESC LIMIT 3; +-----------------+-------------+------+----+ | name | city | year | ct | +-----------------+-------------+------+----+ | Henry Jones | Chicago | 1899 | 1 | | Mac Taylor | New York | 1955 | 1 | | Sarah Connor | Los Angeles | 1959 | 1 | +-----------------+-------------+------+----+
编辑 -添加GROUP BY City到外部查询中,因为具有相同出生年份的人将返回多个值。如果对外部查询进行分组,则可以确保每个城市仅返回一个结果,如果超过一个人的最小值为Birthyear。该ct列将显示该城市中是否存在不止一个人Birthyear
GROUP BY City
ct