Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TSQL problem to calculate differences between two dates inside one table

In MSSQL 2008 I have table and data which looks like this

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 --

Now I trying to make query which is going to tell how long one user was inside according to last exit
something like

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

Sorry if this BAD or ROUGE question and if this is not proper way to ask a question like this. But I am stacked on this for while.

like image 908
adopilot Avatar asked Dec 11 '25 15:12

adopilot


2 Answers

Assuming that

  • same-user sessions do not intersect,

  • there cannot be an EXIT record without the corresponding ENTER record,

you could try the following:

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'
like image 81
Andriy M Avatar answered Dec 14 '25 09:12

Andriy M


Using CTE's you can do

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

This solution however assumes that there is always an exit record than that record always matches to the immediately preceeding entry record

like image 30
Bob Vale Avatar answered Dec 14 '25 07:12

Bob Vale



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!