鉴于这种数据集:

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个最古老的人,但其中只有一个每一个城市。

如果这只是三个最古老的,就是...

  • 亨利*琼斯/芝加哥
  • Mac Taylor/纽约
  • Egon斯宾格勒/纽约

但是由于两个Egon斯宾格勒和Mac*泰勒是位于纽约,埃贡斯宾格勒将下降了,下一个(莎拉*康纳洛杉矶)会来代替。

任何优雅的解决方案?

更新:

目前的变化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分钟),但移动的子查询的加入将加快速度了很多。它花了大约0.15秒钟约。1mio行在我的测试环境。我有一个索引"城市,Birthyear"和第二个只是在"Birthyear".

注:这是相关的。

有帮助吗?

解决方案

可能不是最优雅的解决方案,而且性能的 IN 可能遭受较大的表格。

嵌套的查询得到最低 Birthyear 每个城市。只记录有谁有这个 Birthyear 是匹配的在外层查询。订按年龄后限制到3的结果得到你的最古老的3人,他们也是最古老在他们的城市(Egon斯宾格勒降了..)

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

其他提示

这可能不是最优雅和最快捷的解决方案,但它应的工作。我期待着看到的解决方案的真实数据库大师。

select p.* from people p,
(select city, max(age) as mage from people group by city) t
where p.city = t.city and p.age = t.mage
order by p.age desc

类似的东西吗?

SELECT
  Id, Name, City, Birthyear
FROM
  TheTable
WHERE
  Id IN (SELECT TOP 1 Id FROM TheTable i WHERE i.City = TheTable.City ORDER BY Birthyear)

不漂亮但是应该的工作也与多人用相同的出生日期:

测试数据:

select id, name, city, dob 
into people
from
(select 1 id,'Egon Spengler' name, 'New York' city , 1957 dob
union all select 2, 'Mac Taylor','New York', 1955
union all select 3, 'Sarah Connor','Los Angeles', 1959
union all select 4, 'Jean-Luc Picard','La Barre', 2305
union all select 5, 'Ellen Ripley','Nostromo', 2092
union all select 6, 'James T. Kirk','Riverside', 2233
union all select 7, 'Henry Jones','Chicago', 1899
union all select 8, 'Blah','New York', 1955) a

查询:

select 
    * 
from 
    people p
    left join people p1
    ON 
        p.city = p1.city
        and (p.dob > p1.dob and p.id <> p1.id)
        or (p.dob = p1.dob and p.id > p1.id)
where
    p1.id is null
order by 
    p.dob

@怪

更新 刚刚发现其良好使用,使用代替的。它将消除重复列在的结果。

SELECT P.*, COUNT(*) AS ct
   FROM people P
   JOIN (SELECT City, MIN(Birthyear) AS Birthyear
              FROM people 
              GROUP by City) P2 USING(Birthyear, City)
   GROUP BY P.City
   ORDER BY P.Birthyear ASC 
   LIMIT 10;

原来的职位

嗨,我已经试过使用更新的查询,但我得到了错误的结果直到我加额外的条件来加入(还额外的列入参加选择)。转到您的查询,我使用这个:

SELECT P.*, COUNT(*) AS ct
   FROM people P
   JOIN (SELECT City, MIN(Birthyear) AS Birthyear
              FROM people 
              GROUP by City) P2 ON P2.Birthyear = P.Birthyear AND P2.City = P.City
   GROUP BY P.City
   ORDER BY P.Birthyear ASC 
   LIMIT 10;

在理论上你应该不需要最后一组由P.城市,但是我已经离开这里现在,只在情况。可能去除它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top