SQL group by:选择另一列有其最小值/最大值的值
Posted
技术标签:
【中文标题】SQL group by:选择另一列有其最小值/最大值的值【英文标题】:SQL group by: select value where another column has its min/max 【发布时间】:2017-09-05 07:37:12 【问题描述】:我想按一列分组,获取第二列的最小值和最大值,并且(这是棘手的部分!)从第三列中获取值,其中第二列在组中具有最小值。
例子:
我的表:
ID TS GRP
==================
1 20 A
2 20 B
3 10 A
4 30 A
5 10 B
6 40 A
期望的结果(ID 应该是 TS 最小的记录中的值):
ID MIN_TS MAX_TS GRP
============================
3 10 40 A
5 10 20 B
总的来说,分组查询很简单:
SELECT <???> AS ID, MIN(TS) AS MIN_TS, MAX(TS) AS MAX_TS, GRP
FROM MyTable
GROUP BY GRP
但是 ID 部分呢?它不适用于分组,对吗?但为什么?最好的解决方法是什么?
【问题讨论】:
您需要 JOIN 才能找到该行。 出现平局怎么办?或者它们不能发生(即您对 TS + GRP 有独特的约束)? 你是对的,这就是为什么它不适用于分组的原因...... 【参考方案1】:在子查询中进行聚合,然后在另一个子查询中查找每个组的 ID:
SELECT
(SELECT TOP(1) id FROM MyTable WHERE grp = agg.grp ORDER BY ts DESC) AS id,
min_ts, max_ts, grp
FROM (SELECT min(ts) AS min_ts, max(ts) AS max_ts, grp
FROM MyTable
GROUP BY grp) agg
或者使用窗口函数:
SELECT id, min_ts, max_ts, grp
FROM (SELECT
id,
min(ts) OVER (PARTITION BY grp) min_ts,
max(ts) OVER (PARTITION BY grp) max_ts,
grp,
row_number OVER (PARTITION BY grp ORDER BY ts) rn
FROM MyTable)
WHERE rn = 1;
此查询使用窗口函数计算每个组的min_ts
和max_ts
,然后过滤以仅包含每个组的第一行(按ts
排序)。
【讨论】:
我更喜欢使用窗口函数的第二种解决方案。 请注意,排名函数在非常大的数据集上非常慢。以上是关于SQL group by:选择另一列有其最小值/最大值的值的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 2012 中的 group_concat 与 ORDER BY 另一列