关于postgresql:在SQL连接结果中查找组最大值

Finding group maxes in SQL join result

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
SQL: Select first row in each GROUP BY group?

两个SQL表。 一位参赛者有很多参赛作品:

1
2
3
4
5
6
7
8
9
Contestants     Entries
Id   Name       Id  Contestant_Id  Score
--   ----       --  -------------  -----
1    Fred       1   3              100
2    Mary       2   3              22
3    Irving     3   1              888
4    Grizelda   4   4              123
                5   1              19
                6   3              50

低分获胜。 需要检索按分数排序的所有参赛者的当前最佳分数:

1
2
3
4
5
6
Best Entries Report
Name     Entry_Id  Score
----     --------  -----
Fred     5         19
Irving   2         22
Grizelda 4         123

我当然可以通过许多查询来完成这项工作。 我的问题是,是否有办法通过一个有效的SQL查询获得结果。 我几乎可以看到如何用GROUP BY来做,但不完全。

如果它是相关的,环境是Rails ActiveRecord和PostgreSQL。


这是具体的postgresql方式:

1
2
3
4
SELECT DISTINCT ON (c.id) c.name, e.id, e.score
FROM Contestants c
JOIN Entries e ON c.id = e.Contestant_id
ORDER BY c.id, e.score

有关DISTINCT ON的详细信息在这里。

我的SQLFiddle与示例。

UPD按分数订购结果:

1
2
3
4
5
6
SELECT *
FROM (SELECT DISTINCT ON (c.id) c.name, e.id, e.score
      FROM Contestants c
      JOIN Entries e ON c.id = e.Contestant_id
      ORDER BY c.id, e.score) t
ORDER BY score

这个简单的查询应该做的伎俩..

1
2
3
4
5
SELECT contestants.name AS name, entries.id AS entry_id,  MIN(entries.score) AS score
FROM entries
JOIN contestants ON contestants.id = entries.contestant_id
GROUP BY name
ORDER BY score

这会抓住每个参赛者的最低分数并命令他们ASC


其中一个解决方案是

1
2
3
SELECT MIN(e.score),c.name,c.id FROM entries e
INNER JOIN contestants c ON e.contestant_id = c.id
GROUP BY e.contestant_id,c.name,c.id

这是一个例子
http://sqlfiddle.com/#!3/9e307/27


我对PostgreSQL并不熟悉,但这些内容应该有效:

1
2
3
4
SELECT c.*, s.Score
FROM Contestants c
JOIN (SELECT MIN(Score) Score, Contestant_Id FROM Entries GROUP BY Contestant_Id) s
ON c.Id=s.Contestant_Id

最简单的方法是使用排名函数:

1
2
3
4
5
6
7
8
SELECT name, Entry_id, score
FROM (SELECT e.*, c.name,
             ROW_NUMBER() OVER (partition BY e.contestant_id ORDER BY score) AS seqnum
      FROM entries e JOIN
           contestants c
           ON c.Contestant_id = c.id
     ) ec
WHERE seqnum = 1