Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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 2008的不同记录之间的部分和_Sql_Sql Server_Sql Server 2008_Sum_Gaps And Islands - Fatal编程技术网

使用SQL 2008的不同记录之间的部分和

使用SQL 2008的不同记录之间的部分和,sql,sql-server,sql-server-2008,sum,gaps-and-islands,Sql,Sql Server,Sql Server 2008,Sum,Gaps And Islands,我试图在SQL 2008中解决这个问题。我有一张这样的桌子: DECLARE @table TABLE ( TimeStamp DATETIME, val INT, typerow VARCHAR(3) ); INSERT INTO @table(TimeStamp, val, typerow) VALUES ('2018-06-03 13:30:00.000', 6, 'out'), ('2018-

我试图在SQL 2008中解决这个问题。我有一张这样的桌子:

DECLARE @table TABLE (
    TimeStamp        DATETIME,
    val              INT,
    typerow          VARCHAR(3)
);

INSERT INTO @table(TimeStamp, val, typerow)
VALUES
   ('2018-06-03 13:30:00.000', 6, 'out'),
   ('2018-06-03 14:10:00.000', 8, 'out'),
   ('2018-06-03 14:30:00.000', 3, 'in'),
   ('2018-06-03 15:00:00.000', 9, 'out'),
   ('2018-06-03 15:30:00.000', 4, 'out'),
   ('2018-06-03 16:00:00.000', 2, 'out'),
   ('2018-06-03 17:05:00.000', 8, 'in'),
   ('2018-06-03 17:30:00.000', 0, 'out'),
   ('2018-06-03 18:15:00.000', 7, 'out'),
   ('2018-06-03 18:30:00.000', 1, 'in'),
   ('2018-06-03 19:00:00.000', 5, 'out')
此表包含不同的时间戳,具有相对值val和一个二进制列('in'/'out')typerow

考虑到@table按时间戳升序排序,我需要找到一种方法来获得一个表,其中
typerow='in'
的每一行在val列中包含其当前值加上val字段中所有先前整数的总和,其中
typerow='out'
,直到上一个
typerow='in'
记录。 自然地,对于
typerow='in'
的第一条记录,总和将扩展到@table的第一条记录

2018-06-03 13:30:00.000    6      out
2018-06-03 14:10:00.000    8      out
2018-06-03 14:30:00.000    17     in  -- 6 + 8 + 3
2018-06-03 15:00:00.000    9      out
2018-06-03 15:30:00.000    4      out
2018-06-03 16:00:00.000    2      out
2018-06-03 17:05:00.000    23     in  -- 9 + 4 + 2 + 8
2018-06-03 17:30:00.000    0      out
2018-06-03 18:15:00.000    7      out
2018-06-03 18:30:00.000    8      in  -- 0 + 7 + 1
2018-06-03 19:00:00.000    5      out
考虑到@table将以这种方式生成数百条记录,我的第一个想法是创建一个新的id列,并将相同的id关联到同一求和中涉及的所有记录(可能通过递归CTE实现这一点?),以获得以下结果:

2018-06-03 13:30:00.000    6      out    1
2018-06-03 14:10:00.000    8      out    1
2018-06-03 14:30:00.000    17     in     1
2018-06-03 15:00:00.000    9      out    2
2018-06-03 15:30:00.000    4      out    2
2018-06-03 16:00:00.000    2      out    2
2018-06-03 17:05:00.000    23     in     2
2018-06-03 17:30:00.000    0      out    3
2018-06-03 18:15:00.000    7      out    3
2018-06-03 18:30:00.000    8      in     3
2018-06-03 19:00:00.000    5      out    don't care for this element
还有一个新的专栏,比如

SELECT SUM(vals) OVER (PARTITION BY id ORDER BY id) AS partial_sum
使用部分和更新val列,其中
typerow='in'
。 考虑到我的SQL Server版本,我不知道如何正确创建新的id列,也不知道这是否是一个好的解决方案


提前感谢您的支持,欢迎您提出任何建议。

这是一个缺口和孤岛问题,每个孤岛都以“in”记录结束,您希望对每个孤岛中的值求和

这里有一种方法,它使用以下“in”的计数来定义组,然后对每个组进行窗口求和

select timestamp,
    case when val = 'out' 
        then val
        else sum(val) over(partition by grp order by timestamp)
    end as val,
    typerow
from (
    select t.*,
        sum(case when typerow = 'in' then 1 else 0 end) over(order by timestamp desc) grp
    from @table t
) t
order by timestamp

timestamp | val | typerow :---------------------- | --: | :------ 2018-06-03 13:30:00.000 | 6 | out 2018-06-03 14:10:00.000 | 8 | out 2018-06-03 14:30:00.000 | 17 | in 2018-06-03 15:00:00.000 | 9 | out 2018-06-03 15:30:00.000 | 4 | out 2018-06-03 16:00:00.000 | 2 | out 2018-06-03 17:05:00.000 | 23 | in 2018-06-03 17:30:00.000 | 0 | out 2018-06-03 18:15:00.000 | 7 | out 2018-06-03 18:30:00.000 | 8 | in 2018-06-03 19:00:00.000 | 5 | out 时间戳| val | typerow :---------------------- | --: | :------ 2018-06-03 13:30:00.000 2018-06-03 14:10:00.000外出 2018-06-03 14:30:00.000英寸 2018-06-03 15:00:00.000 2018-06-03 15:30:00.000 2018-06-03 16:00:00.000 2018-06-03 17:05:00.000 | 23 |英寸 2018-06-03 17:30:00.000 | 0 | out 2018-06-03 18:15:00.000 2018-06-03 18:30:00.000英寸 2018-06-03 19:00:00.000
这是一个缺口和孤岛问题,其中每个孤岛都以一个“in”记录结束,您希望对每个孤岛中的值求和

这里有一种方法,它使用以下“in”的计数来定义组,然后对每个组进行窗口求和

select timestamp,
    case when val = 'out' 
        then val
        else sum(val) over(partition by grp order by timestamp)
    end as val,
    typerow
from (
    select t.*,
        sum(case when typerow = 'in' then 1 else 0 end) over(order by timestamp desc) grp
    from @table t
) t
order by timestamp

timestamp | val | typerow :---------------------- | --: | :------ 2018-06-03 13:30:00.000 | 6 | out 2018-06-03 14:10:00.000 | 8 | out 2018-06-03 14:30:00.000 | 17 | in 2018-06-03 15:00:00.000 | 9 | out 2018-06-03 15:30:00.000 | 4 | out 2018-06-03 16:00:00.000 | 2 | out 2018-06-03 17:05:00.000 | 23 | in 2018-06-03 17:30:00.000 | 0 | out 2018-06-03 18:15:00.000 | 7 | out 2018-06-03 18:30:00.000 | 8 | in 2018-06-03 19:00:00.000 | 5 | out 时间戳| val | typerow :---------------------- | --: | :------ 2018-06-03 13:30:00.000 2018-06-03 14:10:00.000外出 2018-06-03 14:30:00.000英寸 2018-06-03 15:00:00.000 2018-06-03 15:30:00.000 2018-06-03 16:00:00.000 2018-06-03 17:05:00.000 | 23 |英寸 2018-06-03 17:30:00.000 | 0 | out 2018-06-03 18:15:00.000 2018-06-03 18:30:00.000英寸 2018-06-03 19:00:00.000
谢谢,我不知道缺口和岛屿的问题。您的解决方案简单有效。谢谢,我不知道缺口和孤岛问题。您的解决方案简单有效。