2011-08-01 38 views
3

2008年MSSQL我有表和数据,看起来像这样TSQL问题来计算一个表中两个日期之间的差异

create table #tempData 
(user_id int,type varchar(10),ts datetime) 

insert into #tempData 
select 1,'ENTER','2011-01-30 15:00:00' 
union all 
select 1,'EXIT','2011-01-31 16:00:00' 
union all 
select 1,'ENTER','2011-02-1 18:00:00' 
union all 
select 1,'EXIT','2011-02-10 21:00:00' 
union all 
select 2,'ENTER','2011-01-10 21:00:00' 
union all 
select 2,'EXIT','2011-01-12 21:00:00' 
union all 
select 2,'ENTER','2011-01-13 01:00:00' 
union all 
select 2,'EXIT','2011-01-13 18:00:00' 
--AND SO ON -- 

现在我努力使查询这是要告诉一个用户多么漫长的时间内根据上次退出

user_id,exited,time_in_hours 
1,'2011-01-31 16:00:00',25 
1,'2011-02-10 21:00:00',219 
2,'2011-01-12 21:00:00',48 
2,'2011-01-13 18:00:00',17 

很抱歉,如果这个坏或ROUGE问题,如果这是不是要问这样的问题,正确的方法。 但我在此堆叠了一会儿。

+0

应该发生什么如果用户进入但不退出并继续执行以下步骤。什么是假设 –

+5

应该有一些像SessionId一样在ENTER-EXIT条目之间建立关系。否则这将是一个混乱(和错误!)建立这样的对 - 只是按照行ID增量原则 – sll

+0

同一个用户的会话可以相交吗? –

回答

1

假设

  • 同一用户会话不相交,

  • 不可能有没有相应ENTER记录的退出记录,

,你可以尝试以下方法:

WITH ranked AS (
    SELECT 
    user_id, 
    type, 
    ts, 
    rn = ROW_NUMBER() OVER (PARTITION BY user_id, type ORDER BY ts) 
    FROM #tempData 
) 
SELECT 
    tx.user_id, 
    exited = tx.ts, 
    hours = DATEDIFF(HOUR, tn.ts, tx.ts) 
FROM ranked tn 
    INNER JOIN ranked tx ON tn.user_id = tx.user_id AND tn.rn = tx.rn 
WHERE tn.type = 'ENTER' 
    AND tx.type = 'EXIT' 
0

试试这个:

SELECT user_id, exitTable.ts AS exited, DATEDIFF(hour, exitTable.ts, enterTable.ts) AS time_in_hours 
FROM yourTable enterTable 
    INNER JOIN yourTable exitTable 
     ON enterTable.user_id = exitTable.user_id 
      and exitTable.ts > enterTable.ts 
        and exitTable.type = 'EXIT' 
WHERE enterTable.type = 'ENTER' 
    and entertable.ts = (SELECT MAX(ts) FROM yourTable WHERE yourTable.user_id = enterTable.user_id AND type = 'ENTER') 

一字半句的解释...

WHERE子句将行限制到最后输入每个USER_ID。 JOIN子句将该行与入口后有一段时间的EXIT结合在一起。

+0

这将如何工作...我认为它会计算差异b/w'2011-01-30 15:00:00'和'2011-02-10 21:00:00'即第一行与最后一行相同用户即用户标识1 –

+0

这将排除尚未过期的会话。 – Narnian

+0

WHERE子句将行限制为最后一个“ENTER”。 JOIN子句限制与大于所选ENTER的EXIT联合。 – Narnian

1

使用CTE的,你可以做

with 
    exits as (select [user_id],ts from #tempData where type='EXIT'), 
    entries as (select [user_id],ts from #tempData where type='ENTER'), 
    result as (
select 
RANK() over (Partition by a.user_id,b.ts order by a.ts desc) as i, 
a.[user_id],b.ts as 'Last Exited',DATEDIFF(hh,a.ts,b.ts) as [hours] 
from 
    entries a inner join exits b on b.[User_id]=a.[User_id] and a.ts<b.ts 
) 

select user_id,[Last Exited],hours from result where i=1 

然而,这种解决方案假定总有出口记录比记录总是匹配紧接的前项纪录

1

尝试

select a.usr,a.ts enter_date 
,min(b.ts) exit_date, datediff(ss,a.ts,min(b.ts)) diff_in_sec 
from tempData a 
    join tempdata b on a.usr = b.usr and a.ts < b.ts 
where a.type='enter' and b.type='exit' 
group by a.usr,a.ts 
相关问题