Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.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 T-SQL指定产品启动之间的运行天数,并在产品启动时重置为零_Sql Server_Tsql - Fatal编程技术网

Sql server T-SQL指定产品启动之间的运行天数,并在产品启动时重置为零

Sql server T-SQL指定产品启动之间的运行天数,并在产品启动时重置为零,sql-server,tsql,Sql Server,Tsql,我需要指定不同产品发布之间经过的天数。这是我拥有的数据的一个示例: SELECT '2016-01-01' TiD, 1 Launch, NULL DaysBetween INTO #TestingData UNION SELECT '2016-01-02', 0, NULL DaysBetween UNION SELECT '2016-01-03', 0, NULL DaysBetween UNION SELECT '2016-01-04', 1, NULL DaysBetween UNION

我需要指定不同产品发布之间经过的天数。这是我拥有的数据的一个示例:

SELECT '2016-01-01' TiD, 1 Launch, NULL DaysBetween
INTO #TestingData
UNION
SELECT '2016-01-02', 0, NULL DaysBetween
UNION
SELECT '2016-01-03', 0, NULL DaysBetween
UNION
SELECT '2016-01-04', 1, NULL DaysBetween
UNION
SELECT '2016-01-05', 0, NULL DaysBetween; 
我尝试使用此查询:

SELECT TiD
       , Launch
       , COUNT(1) OVER(PARTITION BY Launch ORDER BY TiD) DaysSinceLastLaunch
FROM #TestingData
ORDER BY TiD ASC
但是,它不会将计数重置为零。如果我需要我的最终结果如下:

SELECT '2016-01-01' TiD, 1 Launch, 0 DaysBetween
INTO #CorrectData
UNION
SELECT '2016-01-02', 0, 1 DaysBetween
UNION
SELECT '2016-01-03', 0, 2 DaysBetween
UNION
SELECT '2016-01-04', 1, 0 DaysBetween
UNION
SELECT '2016-01-05', 0, 1 DaysBetween;
我需要做什么?我应该使用光标吗

谢谢

您可以使用递归CTE来完成这项工作。在每一次迭代中,从上一次发布开始,每天都有+1


如果你不能让sqlfiddle正常工作,我可以提供一个sqlfiddle,只要让我知道

这里有一个快速的CTE来完成这项工作。这个答案与另一个答案之间的区别在于CTE的第一部分,它采用了
TOP 1
,而不是
Launch=1
,后者可能返回多行。(老实说,我没有测试过另一个答案)

注意:这假设您总是有连续的天数,您的样本数据表明您有连续的天数

SELECT '2016-01-01' TiD, 1 Launch, NULL DaysBetween
INTO #TestingData
UNION
SELECT '2016-01-02', 0, NULL DaysBetween
UNION
SELECT '2016-01-03', 0, NULL DaysBetween
UNION
SELECT '2016-01-04', 1, NULL DaysBetween
UNION
SELECT '2016-01-05', 0, NULL DaysBetween

;WITH    cte
          AS ( SELECT TOP 1
                        TiD ,
                        Launch ,
                        0 AS DaysBetween
               FROM     #TestingData
               ORDER BY TiD
               UNION    ALL
               SELECT   t1.TiD ,
                        t1.Launch ,
                        CASE WHEN t1.Launch = 1 THEN 0
                             ELSE cte.DaysBetween + 1
                        END AS Launch
               FROM     #TestingData t1
                        INNER JOIN cte ON t1.TiD = DATEADD(DAY, 1, cte.TiD)
             )
    SELECT  *
    FROM    cte

DROP TABLE #TestingData
输出:

TiD         Launch  DaysBetween
2016-01-01  1       0
2016-01-02  0       1
2016-01-03  0       2
2016-01-04  1       0
2016-01-05  0       1

如果您有一个正在启动的项目的相关ID或名称,那么根据该值划分的窗口函数就可以正常工作。
TiD         Launch  DaysBetween
2016-01-01  1       0
2016-01-02  0       1
2016-01-03  0       2
2016-01-04  1       0
2016-01-05  0       1