Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server:对有序集使用Windows函数_Sql Server_Tsql_Aggregate Functions_Window Functions - Fatal编程技术网

Sql server SQL Server:对有序集使用Windows函数

Sql server SQL Server:对有序集使用Windows函数,sql-server,tsql,aggregate-functions,window-functions,Sql Server,Tsql,Aggregate Functions,Window Functions,使用此示例数据集: ID POS QTY 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

使用此示例数据集:

ID POS QTY 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 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 如何按组获取总和(数量)。分组基于POS订购的不同(A和B)

作为:

ID POS数量A B总和(数量) 32 1 50 1 2 250第1组 28220012250第一组 123002300第2组 16 4 400 1 2 900第3组非1组 9855012900第3组不是1组 56 6 600 2 2 1300第4组不是第2组 33 7 700 2 2 1300第4组不是第2组 我尝试了不同的分区方法,但总是得到A和B相同的组


按POS订购很重要,因为相同的A和B构成不同的组。

必须有更漂亮的方法来实现这一点,但这就是我现在得到的:

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
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
其中,原始CTE用于查找每个“分区”的第一行。这假设
POS
没有间隙-但如果有间隙,则可以使用另一个基于
POS
的使用
ROW\u 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
)。

Group by(a+B)不起作用,因为组合2+2=1+3=3+1等。如果您知道B的范围(示例B始终<10*a+B)。不起作用,sum(qty)返回sum()对于具有相同A和BAs POS值的所有行都有间隙,您如何使用ROW_NUMBER()而不是POS作为原始CTE?@P.A-只需在顶部添加一个新CTE,其中NewT为(选择*,ROW_NUMBER()在(按POS排序)上作为@t的NewPOS)然后在查询中当前存在
@t
POS
的任何位置使用
NewT
NewPOS
。谢谢,在使用此新CTE时,使用带有行号()的临时表完成了此操作。
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