SQL 有条件地对不同行求和 Datediff

SQL Sum Datediff different rows conditionally

我不是 DBA,我知道这足以让自己陷入困境,所以请耐心等待。我试图从一组数据中找出日期差异,但仅根据状态更改对记录之间的条件差异求和。我遇到的问题不是根据我需要的规则来计算天数。

使用 SQL 2008 R2,规则如下:

使用:

declare @t table
(
    tranID int,
    orderNum varchar(20),
    oldValue varchar(2000),
    newValue varchar(2000),
tranTime datetime
)

insert into @t values(140,3, NULL, 'Closed', '2013-01-05 12:00:00.000')
insert into @t values(160,4, NULL, 'Defered', '2013-01-07 18:00:00.000')
insert into @t values(101,5, NULL, 'New', '2013-01-01 10:01:00.000')
insert into @t values(111,5, 'New', 'Closed', '2013-01-02 10:00:00.000')
insert into @t values(102,6, NULL, 'New', '2013-01-01 10:02:00.000')
insert into @t values(112,6, 'Open', 'Deferred', '2013-01-02 10:10:00.000')
insert into @t values(132,6, 'Deferred', 'Closed', '2013-01-04 11:00:00.000')
insert into @t values(103,7, NULL, 'New', '2013-01-01 10:03:00.000')
insert into @t values(123,7, 'Ready', 'Closed', '2013-01-03 11:30:00.000')
insert into @t values(133,7, 'Closed', 'Open', '2013-01-04 11:11:00.000')
insert into @t values(143,7, 'Passed', 'Closed', '2013-01-05 12:15:00.000')
insert into @t values(104,8, NULL, 'New', '2013-01-01 10:04:00.000')
insert into @t values(114,8, 'Open', 'Closed', '2013-01-02 10:20:00.000')
insert into @t values(134,8, 'Closed', 'Open', '2013-01-04 11:22:00.000')
insert into @t values(144,8, 'Failed', 'Deferred', '2013-01-05 12:30:00.000')
insert into @t values(154,8, 'Deferred', 'Closed', '2013-01-06 17:00:00.000')

我希望看到类似这样的输出:

orderNum | resolveDays
----------------------
    3    |      0
    4    |      0
    5    |      1
    6    |      1
    7    |      3
    8    |      2

我们有一组订单,其中的交易 ID 根据更改的日期而增加。排序的 tranID 将依次对日期进行排序。要查看根据规则轻松分组的数据,我们需要先按 orderNum 然后按 tranID 进行排序,您可以看到 orderNum 与其匹配的更改按出现顺序排列得很好。 我有一个查询会给我最小和最大日期的日期差异,但这不符合我不添加天数的规则,而订单已关闭或推迟。

Select orderNum
      ,MIN(tranTime)as Opened
      ,MAX(tranTime) as LastClose
      ,DATEDIFF(DAY,MIN(tranTime),MAX(tranTime)) as resolveDays
      ,Count(tranTime) as QtyChanged
from @t 
group by orderNum
order by orderNum

我试图用大小写开关对 orderNum 求和,但无法正确显示计数,这导致我尝试使用 RANK 或 ROW_NUMBER OVER orderNum 在以前的记录并检查 oldValue 和 newValue 的情况,但我缺少连接这些部分的东西。我也一直在研究孤岛和差距解决方案,但我无法将这些点联系起来以获得我预期的结果。我还能在这里尝试什么?

尝试以下查询

DECLARE @t TABLE
(
    tranID INT,
    orderNum VARCHAR(20),
    oldValue VARCHAR(2000),
    newValue VARCHAR(2000),
    tranTime DATETIME
)

INSERT INTO @t VALUES(140,3, NULL, 'Closed', '2013-01-05 12:00:00.000')
INSERT INTO @t VALUES(160,4, NULL, 'Defered', '2013-01-07 18:00:00.000')
INSERT INTO @t VALUES(101,5, NULL, 'New', '2013-01-01 10:01:00.000')
INSERT INTO @t VALUES(111,5, 'New', 'Closed', '2013-01-02 10:00:00.000')
INSERT INTO @t VALUES(102,6, NULL, 'New', '2013-01-01 10:02:00.000')
INSERT INTO @t VALUES(112,6, 'Open', 'Deferred', '2013-01-02 10:10:00.000')
INSERT INTO @t VALUES(132,6, 'Deferred', 'Closed', '2013-01-04 11:00:00.000')
INSERT INTO @t VALUES(103,7, NULL, 'New', '2013-01-01 10:03:00.000')
INSERT INTO @t VALUES(123,7, 'Ready', 'Closed', '2013-01-03 11:30:00.000')
INSERT INTO @t VALUES(133,7, 'Closed', 'Open', '2013-01-04 11:11:00.000')
INSERT INTO @t VALUES(143,7, 'Passed', 'Closed', '2013-01-05 12:15:00.000')
INSERT INTO @t VALUES(104,8, NULL, 'New', '2013-01-01 10:04:00.000')
INSERT INTO @t VALUES(114,8, 'Open', 'Closed', '2013-01-02 10:20:00.000')
INSERT INTO @t VALUES(134,8, 'Closed', 'Open', '2013-01-04 11:22:00.000')
INSERT INTO @t VALUES(144,8, 'Failed', 'Deferred', '2013-01-05 12:30:00.000')
INSERT INTO @t VALUES(154,8, 'Deferred', 'Closed', '2013-01-06 17:00:00.000')
------
DECLARE @TmpTable TABLE 
(
    Id INT,
    tranID INT,
    orderNum VARCHAR(20),
    oldValue VARCHAR(2000),
    newValue VARCHAR(2000),
    tranTime DATETIME
)
------
INSERT INTO @TmpTable
SELECT
    ROW_NUMBER() OVER(PARTITION BY orderNum ORDER BY tranID) Id,
    tranID,
    orderNum,
    oldValue,
    newValue,
    tranTime
FROM
    @t    
------
SELECT 
    CurrentRow.orderNum,
    SUM(
        CASE
            WHEN CurrentRow.newValue = NextRow.oldValue AND 
                 NextRow.oldValue IN ('Closed', 'Deferred') THEN 0
            ELSE ISNULL(DATEDIFF(DAY, CurrentRow.tranTime, NextRow.tranTime), 0) END
        )  AS resolveDays
FROM
    @TmpTable CurrentRow LEFT JOIN 
    @TmpTable NextRow ON CurrentRow.orderNum = NextRow.orderNum AND
                         CurrentRow.Id = (NextRow.Id - 1)
GROUP BY CurrentRow.orderNum

输出:

orderNum             resolveDays
-------------------- -----------
3                    0
4                    0
5                    1
6                    1
7                    3
8                    2