将 ROW_NUMBER() 与聚合函数一起使用
Posted
技术标签:
【中文标题】将 ROW_NUMBER() 与聚合函数一起使用【英文标题】:Using ROW_NUMBER() with aggregate functions 【发布时间】:2020-01-21 14:54:14 【问题描述】:假设我有这个查询:
SELECT id, date, amount, cancelled
FROM transactions
这给了我以下结果:
id date amount ref
1 01/2019 5.00 a
1 02/2019 10.00 b
1 06/2019 20.00 c
2 10/2019 11.00 d
如果有重复的 ID,我怎样才能获得具有 最新日期 以及 所有金额的总和 和 所有连接字符串的 ID参考字段?即:
id date amount ref
1 06/2019 35.00 abc
2 10/2019 11.00 d
这是获取具有最大日期的不同 ID 的 SQL,但我不确定如何聚合金额/参考字段
WITH data_with_date_sequence AS (
SELECT
id
, date
, amount
, ref
, ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS seq
FROM dbo.SomeTable
)
SELECT
id
, date
, amount
, ref
FROM data_with_date_sequence
WHERE seq = 1;
【问题讨论】:
什么版本的 SQL Server? 2017 年推出STRING_AGG
。从 2012 年起支持SUM() OVER ()
。
糟糕忘了说,现在是 2008 年
您考虑过升级吗?根本不支持该版本。
反正我错了; SUM() OVER ()
已于 2005 年推出。 2012 年增加了窗口支持 (ROWS BETWEEN
)。
【参考方案1】:
将window function
与sum()
一起使用:
WITH data_with_date_sequence AS (
SELECT id, date, amount,
ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS seq,
SUM(amount) OVER (PARTITION BY id) AS amount,
STUFF(t.ref, 1, 1, '') AS ref
FROM dbo.SomeTable st CROSS APPLY
( SELECT DISTINCT ','+st1.ref
FROM SomeTable st1
WHERE st1.id = st.id
FOR XML PATH('')
) t(Ref)
)
SELECT id, date, amount, ref
FROM data_with_date_sequence
WHERE seq = 1;
如果您使用的是最新版本,则可以使用STRING_AGG()。
这里是demo。
【讨论】:
感谢您的回答,但串联的字符串仅返回一个 ref 字段,第一个字符已删除。例如,如果您期望abc,def
,则改为 bc
@JanTrindal。 . .那可能您从子查询中删除了,
。我更新了查询版本。
我没有删除它,它与您的查询完全相同。
@JanTrindal。 . .不,CONCAT()
在2008
中不起作用。【参考方案2】:
对于这个用例,我认为不需要窗口函数。请考虑这个聚合查询:
select
id,
max(date) date,
sum(amount) amount,
string_agg(ref, '') within group (order by date) ref
from mytable
group by id
注意:string_agg()
是在 SQL Server 2017 中添加的。
【讨论】:
对不起,我忘了说它是 2008 年以上是关于将 ROW_NUMBER() 与聚合函数一起使用的主要内容,如果未能解决你的问题,请参考以下文章
分区函数Partition By的与row_number()的用法以及与排序rank()的用法详解(获取分组(分区)中前几条记录)(转)