计算唯一数据行之间的时差

时间:2018-03-23 20:24:40

标签: sql sql-server tsql datetime calculated-columns

假设我有一个包含两个字段的表。 Record_CreateddatetimeAction只是一个字符串。数据可能如下所示:

Record_Created      Action
1/11/18 5:24 PM     Action 1
1/11/18 5:32 PM     Action 2
1/17/18 4:41 PM     Action 3
1/17/18 4:41 PM     Action 2
1/17/18 4:44 PM     Action 3
1/18/18 11:12 AM    Action 4
1/18/18 11:12 AM    Action 3
1/18/18 11:13 AM    Action 4
1/25/18 2:44 PM     Action 5

我需要计算不同操作之间的时差(以天为单位),但不仅仅是在各行之间,而是基于每个操作的最后一次出现的唯一操作。所以我的结果数据集应如下所示:

Action  Difference
Action 2    6
Action 3    1
Action 4    0
Action 5    7

考虑到我在此表中有超过一百万条记录可以实现这一目标,最好和最有效的方法是什么?

4 个答案:

答案 0 :(得分:3)

您可以为每种操作类型设置最小和最大日期,并使用datediff获取它们之间的天数:

<form class="form-group">
   <select class="form-control" (change)="changePreset();>
     <option value="">Please choose a preset</option>
     <option value="preset1" >Preset 1</option>
     <option value="preset2" >Preset 2</option>
     <option value="preset3" >Preset 3</option>
     <option value="preset4" >Preset 4</option>
     <option value="preset5" >Preset 5</option>
   </select>
</form>

答案 1 :(得分:1)

如果我理解正确,您希望查看每个操作的最后日期,然后列出按该日期排序的操作,并显示从一个操作到下一个操作的时间跨度。

因此,按行动聚合以获取最后一个日期,然后使用LAG查看上一条记录。

select 
  action, 
  max(record_created),
  date_diff(day,
    lag(max(record_created)) over (order by max(record_created)),
    max(record_created)
  ) as diff;
from actions
group by action
order by action;

此查询还包含第一个操作(差异= null),但我想你不介意。

Rextester演示:http://rextester.com/EAA26233

答案 2 :(得分:0)

我不知道你在哪里采取行动5

declare @T table (dt datetime, action varchar(10));
insert into @T values 
       ('1/11/18 5:24 PM',  'Action 1')
     , ('1/11/18 5:32 PM',  'Action 2')
     , ('1/17/18 4:41 PM',  'Action 3')
     , ('1/17/18 4:41 PM',  'Action 2')
     , ('1/17/18 4:44 PM ', 'Action 3')
     , ('1/18/18 11:12 AM', 'Action 4')
     , ('1/18/18 11:12 AM', 'Action 3')
     , ('1/18/18 11:13 AM', 'Action 4')
     , ('1/25/18 2:44 PM',  'Action 5');

select * from @t order by action, dt desc

select tt.action, tt.dt, tt.leaddt, DATEDIFF(day, tt.leaddt, tt.dt) as diff 
  from ( select t.* 
              , ROW_NUMBER() over (partition by t.action order by t.dt desc) as rn 
              , lead(t.dt)   over (partition by t.action order by t.dt desc) as leaddt 
           from @T t 
       ) tt
where tt.rn = 1 
  and tt.leaddt is not null 
order by tt.action

dt                      action
----------------------- ----------
2018-01-11 17:24:00.000 Action 1
2018-01-17 16:41:00.000 Action 2
2018-01-11 17:32:00.000 Action 2
2018-01-18 11:12:00.000 Action 3
2018-01-17 16:44:00.000 Action 3
2018-01-17 16:41:00.000 Action 3
2018-01-18 11:13:00.000 Action 4
2018-01-18 11:12:00.000 Action 4
2018-01-25 14:44:00.000 Action 5

action     dt                      leaddt                  diff
---------- ----------------------- ----------------------- -----------
Action 2   2018-01-17 16:41:00.000 2018-01-11 17:32:00.000 6
Action 3   2018-01-18 11:12:00.000 2018-01-17 16:44:00.000 1
Action 4   2018-01-18 11:13:00.000 2018-01-18 11:12:00.000 0

答案 3 :(得分:0)

这可能是一种强力解决方案,但它应该可以胜任。逻辑是 1.获取每个操作的最大日期 2.为每个记录分配行号,以便您可以在子查询中进行迭代。 3.计算差异

;WITH cte1 as
(select action, max(record_created) as MaxDt, ROW_Number() OVER(Order by Action) as row_num
 from @YourTable
 group by action
) 

select *, (select DATEDIFF(DAY, b.MaxDT, a.MaxDT) 
            from cte1 b 
           where b.row_num= a.row_num-1 ) as Diff
from cte1 a