mysql 多行唯一,MySQL:选择N行,但在一列中仅包含唯一值

Given this data set:

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

I need to find the 3 oldest persons, but only one of every city.

If it would just be the three oldest, it would be...

Henry Jones / Chicago

Mac Taylor / New York

Egon Spengler / New York

However since both Egon Spengler and Mac Taylor are located in New York, Egon Spengler would drop out and the next one (Sarah Connor / Los Angeles) would come in instead.

Any elegant solutions?

Update:

Currently a variation of PConroy is the best/fastest solution:

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;

His original query with "IN" is extremly slow with big datasets (aborted after 5 minutes), but moving the subquery to a JOIN will speed it up a lot. It took about 0.15 seconds for approx. 1 mio rows in my test environment. I have an index on "City, Birthyear" and a second one just on "Birthyear".

Note: This is related to...

解决方案

Probably not the most elegant of solutions, and the performance of IN may suffer on larger tables.

The nested query gets the minimum Birthyear for each city. Only records who have this Birthyear are matched in the outer query. Ordering by age then limiting to 3 results gets you the 3 oldest people who are also the oldest in their city (Egon Spengler drops out..)

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 |

+-----------------+-------------+------+----+

Edit - added GROUP BY City to outer query, as people with same birth years would return multiple values. Grouping on the outer query ensures that only one result will be returned per city, if more than one person has that minimum Birthyear. The ct column will show if more than one person exists in the city with that Birthyear

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值