如何使用“GROUP BY”在单个查询中查找 SQL 中最高和第二高的条目?
Posted
技术标签:
【中文标题】如何使用“GROUP BY”在单个查询中查找 SQL 中最高和第二高的条目?【英文标题】:How to find the highest and second highest entry in SQL in a single query using `GROUP BY`? 【发布时间】:2021-12-25 06:34:54 【问题描述】:假设这是提供的表格。
PID | TID | Type | Freq |
---|---|---|---|
1 | 1 | A | 3 |
1 | 1 | A | 2 |
1 | 1 | A | 1 |
1 | 1 | B | 3 |
1 | 2 | A | 4 |
1 | 2 | B | 5 |
我想写一个查询来得到这样的输出。
PID | TID | Type | Max_Freq_1 | Max_Freq_2 |
---|---|---|---|---|
1 | 1 | A | 3 | 2 |
1 | 1 | B | 3 | NULL |
1 | 2 | A | 4 | NULL |
1 | 2 | B | 5 | NULL |
也就是说,给定PID
、TID
、Type
的组合,最高频率和次高频率是多少?如果表中没有足够数量的条目,则将第二高设置为NULL
【问题讨论】:
【参考方案1】:如果您的数据库可以使用窗口函数,那么可以通过 DENSE_RANK 函数计算前 2 个 Freq。
SELECT PID, TID, Type
, MAX(CASE WHEN Rnk = 1 THEN Freq END) AS Max_Freq_1
, MAX(CASE WHEN Rnk = 2 THEN Freq END) AS Max_Freq_2
FROM
(
SELECT PID, TID, Type, Freq
, DENSE_RANK() OVER (PARTITION BY PID, TID, Type ORDER BY Freq DESC) AS Rnk
FROM YourTable t
) q
GROUP BY PID, TID, Type
ORDER BY PID, TID, Type
pid | tid | type | max_freq_1 | max_freq_2 |
---|---|---|---|---|
1 | 1 | A | 3 | 2 |
1 | 1 | B | 3 | null |
1 | 2 | A | 4 | null |
1 | 2 | B | 5 | null |
如果 ROW_NUMBER 不可用,请试试这个。
SELECT PID, TID, Type
, MAX(CASE WHEN Rnk = 1 THEN Freq END) AS Max_Freq_1
, MAX(CASE WHEN Rnk = 2 THEN Freq END) AS Max_Freq_2
FROM
(
SELECT t1.PID, t1.TID, t1.Type, t1.Freq
, COUNT(DISTINCT t2.Freq) AS Rnk
FROM YourTable t1
LEFT JOIN YourTable t2
ON t2.PID = t1.PID
AND t2.TID = t1.TID
AND t2.Type = t1.Type
AND t2.Freq >= t1.Freq
GROUP BY t1.PID, t1.TID, t1.Type, t1.Freq
) q
GROUP BY PID, TID, Type
ORDER BY PID, TID, Type
dbfiddle here
上的演示【讨论】:
【参考方案2】:这是我在 PostgreSQL 上提出的。使用 row_number 之类的窗口函数是获得所需结果的最简单方法。
with t as (
select *, row_number() over (partition by pid, tid, "type" order by freq desc) as r
from test_so
) select pid, tid, "type", max(case when r = 1 then freq end) as "highest", max(case when r = 2 then freq end) as "second_highest"
from t
group by pid, tid, "type"
【讨论】:
以上是关于如何使用“GROUP BY”在单个查询中查找 SQL 中最高和第二高的条目?的主要内容,如果未能解决你的问题,请参考以下文章
如何在mongodb的单个查询中添加具有不同条件输出的Multiple Group By?
在 group by 中使用 datetime 日期并在单个 SELECT 中使用 order by 与使用子查询