SQL Server:使用有序集的 Windows 函数
Posted
技术标签:
【中文标题】SQL Server:使用有序集的 Windows 函数【英文标题】:SQL Server: Use of Windows Function with ordered set 【发布时间】:2015-03-19 11:12:06 【问题描述】:使用此示例数据集:
ID POS 数量 A B 32 1 50 1 2 28 2 200 1 2 12 3 300 2 2 16 4 400 1 2 98 5 500 3 1 56 6 600 2 2 33 7 700 2 2如何按组获取 SUM(QTY)。组基于不同的(A 和 B)ORDERED BY POS !!!
作为:
ID POS QTY A B SUM(QTY) 32 1 50 1 2 250 第 1 组 28 2 200 1 2 250 第 1 组 12 3 300 2 2 300 第 2 组 16 4 400 1 2 900 第 3 组不是 1 98 5 500 1 2 900 第 3 组不是 1 56 6 600 2 2 1300 组 4 不是 2 33 7 700 2 2 1300 组 4 不是 2我用 PARTITION BY 尝试了不同的解决方案,但总是得到 A 和 B 相同的组。
POS 的顺序很重要,因为相同的 A 和 B 形成不同的组。
【问题讨论】:
按 (A+B) 分组不起作用,因为组合 2+2 = 1+3 = 3+1 等。如果您知道 B 的范围(例如 B 总是 【参考方案1】:必须有更漂亮的方法来做到这一点,但这是我现在所拥有的:
declare @t table (ID int,POS int,QTY int,A int,B int)
insert into @t(ID,POS,QTY,A,B) values
(32,1, 50,1,2), (28,2,200,1,2), (12,3,300,2,2), (16,4,400,1,2),
(98,5,500,1,2), (56,6,600,2,2), (33,7,700,2,2)
;With Origins as (
select t1.*
from @t t1
left join
@t t2
on
t1.POS = t2.POS + 1 and
t1.A = t2.A and
t1.B = t2.B
where t2.POS is null
)
select
t.*,SUM(t.QTY) OVER (PARTITION BY o.POS) as Qty
from
@t t
inner join
Origins o
on
t.A = o.A and
t.B = o.B and
t.POS >= o.POS
left join
Origins o_other
on
t.A = o_other.A and
t.B = o_other.B and
t.POS >= o_other.POS and
o_other.POS > o.POS
where
o_other.POS is null
Origins CTE 用于查找每个“分区”的第一行。这假设 POS
没有间隙 - 但如果确实如此,则可以使用基于 POS
的另一个使用 ROW_NUMBER()
的 CTE。
最后的查询然后通过找到最近的具有较低 POS
值的行将每一行连接到“正确的”Origins
行,然后我们将其用作分区的键。
结果:
ID POS QTY A B Qty
----------- ----------- ----------- ----------- ----------- -----------
32 1 50 1 2 250
28 2 200 1 2 250
12 3 300 2 2 300
16 4 400 1 2 900
98 5 500 1 2 900
56 6 600 2 2 1300
33 7 700 2 2 1300
(我更改了示例数据以匹配您的预期结果,而不是您问题顶部显示的内容,其中有一个 3,1
行用于条目 5
)。
【讨论】:
由于 POS 值有差距,您如何使用 ROW_NUMBER() 代替 POS 来表示 Origins CTE? @P.A - 只需在顶部添加一个新的 CTEWith NewT as (select *,ROW_NUMBER() OVER (ORDER by POS) as NewPOS from @t)
,然后在查询中当前存在 @t
和 POS
的任何位置使用 NewT
和 NewPOS
。
谢谢,完成了,使用带有 row_number() 的临时表,就像您使用这个新的 CTE。【参考方案2】:
select t1.*, t2.sum_qty
from your_table t1
join
(
select a, b, sum(qty) as sum_qty
from your_table
group by a, b
) t2 on t1.a = t2.a and t1.b = t2.b
order by t1.pos
【讨论】:
不起作用,sum(qty) 为所有具有相同 A 和 B 的行返回 sum()以上是关于SQL Server:使用有序集的 Windows 函数的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft SQL Server 2016,T-SQL:根据各个日期获取数据集的日期范围