SQL 有条件地对不同行求和 Datediff
SQL Sum Datediff different rows conditionally
我不是 DBA,我知道这足以让自己陷入困境,所以请耐心等待。我试图从一组数据中找出日期差异,但仅根据状态更改对记录之间的条件差异求和。我遇到的问题不是根据我需要的规则来计算天数。
使用 SQL 2008 R2,规则如下:
- oldValue 到 newValue 的记录(NULL 到 'anything')将始终 = MIN;
- 仅当 oldValue 不等于 Close 或 Deferred 时才添加天数;
- 不要在先前已知的 newValue 等于当前记录的 oldValue 且等于 Closed 或 Deferred 的更改之间添加天数
使用:
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
我不是 DBA,我知道这足以让自己陷入困境,所以请耐心等待。我试图从一组数据中找出日期差异,但仅根据状态更改对记录之间的条件差异求和。我遇到的问题不是根据我需要的规则来计算天数。
使用 SQL 2008 R2,规则如下:
- oldValue 到 newValue 的记录(NULL 到 'anything')将始终 = MIN;
- 仅当 oldValue 不等于 Close 或 Deferred 时才添加天数;
- 不要在先前已知的 newValue 等于当前记录的 oldValue 且等于 Closed 或 Deferred 的更改之间添加天数
使用:
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