我有两个表:section 和 takes。 我制作了一个自然连接表来查找有多少人参加了某门类(class)。即:
course_id | sec_id | semester | year | count
-----------+--------+----------+------+-------
CS-101 | 1 | Fall | 2009 | 6
CS-347 | 1 | Fall | 2009 | 2
PHY-101 | 1 | Fall | 2009 | 1
使用这个自然连接表,我想找到注册学生人数最多的类(class)。
SELECT course_id, sec_id, semester, year, tb.count
FROM
(SELECT course_id, sec_id, semester, year, COUNT(*)
FROM section
NATURAL JOIN takes
WHERE (semester, year) = ('Fall', 2009)
GROUP BY course_id, sec_id, semester, year) AS tb
WHERE
tb.count =
(SELECT max(tb.count)
FROM
(SELECT course_id, sec_id, semester, year, COUNT(*)
FROM section
NATURAL JOIN takes
WHERE (semester, year) = ('Fall', 2009)
GROUP BY course_id, sec_id, semester, year) AS tb
) ;
这是我试过的,效果很好!显示:
course_id | sec_id | semester | year | count
-----------+--------+----------+------+-------
CS-101 | 1 | Fall | 2009 | 6
但代码似乎过于冗余,所以我想也许有更简单的方法来实现它。有没有一种方法可以得到相同的答案,而无需在 where 子句中重新重复相同的连接过程?
最佳答案
在您的情况下,您可以使用 LIMIT
子句。
先把最大值排到最前面,然后只给出第一条记录:
SELECT
<your query>
ORDER BY count DESC
LIMIT 1
如果你想获得所有最大值(例如,如果有两条 count = 6
的记录)你可以使用 rank()
window function :
SELECT
*
FROM (
SELECT
*,
rank() OVER (ORDER BY count DESC)
FROM
<your query>
) s
WHERE rank = 1
rank()
将增加的值添加到每个唯一值(在这种情况下添加到 count
值)。绑定(bind)值获得相同的排名值。第一个始终是 1
,因此您可以在其后进行过滤。
在某些情况下,最好按照原来的方式进行,但将冗余代码提取到 CTE (WITH
clause) 中:
demo:db<>fiddle (对于这个没有任何连接和进一步子查询的小示例,CTE 似乎要快一点;您可以试一试)
WITH cte AS (
<your query>
)
SELECT
*
FROM
cte
WHERE count = (SELECT max(count) FROM cte)
关于postgresql - 查找自然连接表的最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58265312/