Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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-获取“X”连续值的总和,其中X是另一行中的整数(带类别)_Sql_Sql Server_Tsql_Sum - Fatal编程技术网

SQL-获取“X”连续值的总和,其中X是另一行中的整数(带类别)

SQL-获取“X”连续值的总和,其中X是另一行中的整数(带类别),sql,sql-server,tsql,sum,Sql,Sql Server,Tsql,Sum,比如说,我想对当前行中的所有值求和,直到提供的计数为止。见下表: 例如: 类别A,第1行:10+15+25=50,因为它由于计数而将第1行添加到第3行 类别A,第2行:15+25+30+40=110,因为它由于计数而将第2行添加到第5行 类别A第5行:40+60=100,因为它添加了第5行和第6行。由于计数为5,但类别结束于第6行,因此它将所有可用数据相加,即仅第5行和第6行,因此值为100。 B类也是如此。 我该怎么做?试试这个: DECLARE @DataSource TABLE (

比如说,我想对当前行中的所有值求和,直到提供的计数为止。见下表:

例如:

类别A,第1行:10+15+25=50,因为它由于计数而将第1行添加到第3行 类别A,第2行:15+25+30+40=110,因为它由于计数而将第2行添加到第5行 类别A第5行:40+60=100,因为它添加了第5行和第6行。由于计数为5,但类别结束于第6行,因此它将所有可用数据相加,即仅第5行和第6行,因此值为100。 B类也是如此。 我该怎么做?

试试这个:

DECLARE @DataSource TABLE 
(
    [Category] CHAR(1)
   ,[Row Number] BIGINT
   ,[Quantity] INT
   ,[Count] INT
);

INSERT INTO @DataSource ([Category], [Row Number], [Quantity], [Count])
VALUES ('A', 1, 10, 3)
      ,('A', 2, 15, 4)
      ,('A', 3, 25, 2)
      ,('A', 4, 30, 1)
      ,('A', 5, 40, 5)
      ,('A', 6, 60, 2)
      --
      ,('B', 1, 12, 2)
      ,('B', 2, 13, 3)
      ,('B', 3, 17, 1)
      ,('B', 4, 11, 2)
      ,('B', 5, 10, 5)
      ,('B', 6, 7, 3);

SELECT *
FROM @DataSource E
CROSS APPLY
(
    SELECT SUM(I.[Quantity])
    FROM @DataSource I
    WHERE I.[Row Number] <= E.[Row Number] + E.[Count] - 1
        AND I.[Row Number] >= E.[Row Number]
        AND E.[Category] = I.[Category]
) DS ([Sum]);
试试这个:

DECLARE @DataSource TABLE 
(
    [Category] CHAR(1)
   ,[Row Number] BIGINT
   ,[Quantity] INT
   ,[Count] INT
);

INSERT INTO @DataSource ([Category], [Row Number], [Quantity], [Count])
VALUES ('A', 1, 10, 3)
      ,('A', 2, 15, 4)
      ,('A', 3, 25, 2)
      ,('A', 4, 30, 1)
      ,('A', 5, 40, 5)
      ,('A', 6, 60, 2)
      --
      ,('B', 1, 12, 2)
      ,('B', 2, 13, 3)
      ,('B', 3, 17, 1)
      ,('B', 4, 11, 2)
      ,('B', 5, 10, 5)
      ,('B', 6, 7, 3);

SELECT *
FROM @DataSource E
CROSS APPLY
(
    SELECT SUM(I.[Quantity])
    FROM @DataSource I
    WHERE I.[Row Number] <= E.[Row Number] + E.[Count] - 1
        AND I.[Row Number] >= E.[Row Number]
        AND E.[Category] = I.[Category]
) DS ([Sum]);

可以使用窗口函数执行此操作:

with tt as (
      select t.*,
             sum(quantity) over (partition by category order by rownumber) as running_quantity,
             max(rownumber) over (partition by category) as max_rownumber
      from t
     )
select tt.*,
       coalesce(tt2.running_quantity, ttlast.running_quantity) - tt.running_quantity + tt.quantity
from tt left join
     tt tt2
     on tt2.category = tt.category and
        tt2.rownumber = tt.rownumber + tt.count - 1 left join
     tt ttlast
     on ttlast.category = tt.category and
        ttlast.rownumber = ttlast.max_rownumber
order by category, rownumber;
我可以想象,在某些情况下,这会快得多——特别是当计数值相对较大时。对于较小的count值,横向连接可能更快,但值得检查性能是否重要

实际上,纯窗口函数方法可能是最好的方法:

with tt as (
      select t.*,
             sum(quantity) over (partition by category order by rownumber) as running_quantity
      from t
     )
select tt.*,
       (coalesce(lead(tt.running_quantity, tt.count - 1) over (partition by tt.category order by tt.rownumber),
                 first_value(tt.running_quantity) over (partition by tt.category order by tt.rownumber desc)
                ) - tt.running_quantity + tt.quantity
       )
from tt
order by category, rownumber;

是一个dbfiddle。

您可以使用窗口功能来完成此操作:

with tt as (
      select t.*,
             sum(quantity) over (partition by category order by rownumber) as running_quantity,
             max(rownumber) over (partition by category) as max_rownumber
      from t
     )
select tt.*,
       coalesce(tt2.running_quantity, ttlast.running_quantity) - tt.running_quantity + tt.quantity
from tt left join
     tt tt2
     on tt2.category = tt.category and
        tt2.rownumber = tt.rownumber + tt.count - 1 left join
     tt ttlast
     on ttlast.category = tt.category and
        ttlast.rownumber = ttlast.max_rownumber
order by category, rownumber;
我可以想象,在某些情况下,这会快得多——特别是当计数值相对较大时。对于较小的count值,横向连接可能更快,但值得检查性能是否重要

实际上,纯窗口函数方法可能是最好的方法:

with tt as (
      select t.*,
             sum(quantity) over (partition by category order by rownumber) as running_quantity
      from t
     )
select tt.*,
       (coalesce(lead(tt.running_quantity, tt.count - 1) over (partition by tt.category order by tt.rownumber),
                 first_value(tt.running_quantity) over (partition by tt.category order by tt.rownumber desc)
                ) - tt.running_quantity + tt.quantity
       )
from tt
order by category, rownumber;

是一把小提琴。

你试过什么?你在哪里卡住了?请让我们看看你的尝试。你尝试了什么?你在哪里卡住了?请让我们看看你的尝试。是的!那确实管用!这方面已经没有问题了。我现在担心的是,如果我有一个非常大的数据,处理时间是超慢的,就像我现在正在做的一样,现在仍然执行查询超过一个小时,但无论如何谢谢你@LawrenceWayneRagudo您是从一个表中读取还是查询更复杂?是的!那确实管用!这方面已经没有问题了。我现在担心的是,如果我有一个非常大的数据,处理时间是超慢的,就像我现在正在做的一样,现在仍然执行查询超过一个小时,但无论如何谢谢你@你是从一个表中读取数据还是查询更复杂?