Reputation: 63
I have a setting table:
create table settings(
id int
, date datetime
, user varchar(20)
, status varchar(10)
);
insert into settings values
(1 , '2020-07-10 14:36:06', 'user1', 'INACTIVE'),
(1 , '2020-07-10 14:39:54', 'user1', 'ACTIVE'),
(1 , '2020-07-10 14:44:06', 'user1', 'INACTIVE'),
(1 , '2020-07-10 14:46:06', 'user2', 'INACTIVE'),
(1 , '2020-07-10 14:49:06', 'user2', 'SCHEDULED'),
(1 , '2020-07-10 14:55:06', 'user2', 'ACTIVE'),
(2 , '2020-07-12 14:36:06', 'user1', 'INACTIVE'),
(2 , '2020-07-13 14:39:54', 'user1', 'INACTIVE'),
(2 , '2020-07-13 16:44:06', 'user1', 'ACTIVE'),
(2 , '2020-07-15 14:46:06', 'user3', 'INACTIVE'),
(2 , '2020-07-15 15:49:06', 'user3', 'INACTIVE'),
(2 , '2020-07-17 14:46:06', 'user3', 'ACTIVE')
;
example code with insert code is in sql fiddle
The process starts from INACTIVE
status and it is scheduled by system then user could change to SCHEDULED
or ACTIVE
.
I need to find rows which have ACTIVE
status but only these one which before is row with INACTIVE
status grouped by user. Specific case (not sure if it is possible) to find rows with ACTIVE
status but if previous rows have SCHEDULED -> INACTIVE
sequence.
I selected on the below screenshot which rows should be returned:
I was trying with it but the result should return previous row under current row.
select * from (
select @rownum:=@rownum+1 row, a.*
from settings a
where a.status = 'ACTIVE'
) as cr
LEFT JOIN (SELECT @rownum2:=@rownum2+1 row, b.* FROM settings b
where b.status = 'INACTIVE' ) as pr
on cr.id = pr.id and cr.date > pr.date
Upvotes: 1
Views: 708
Reputation: 882
You could use self-join to do this.
After doing self-join, from one table (say A) get ACTIVE time for each date and from another table (say B) get Inactive time where B.date<A.date
.
Then you can perform other operation on both date like getting time duration or something.
Check fiddle here : http://sqlfiddle.com/#!9/84789e/23
Query :
SELECT A.user,max(B.date) as Inactive,min(A.date) as Active
FROM settings A JOIN settings B
ON A.id=B.id and A.user=B.user
WHERE A.status = 'ACTIVE'
AND B.status = 'INACTIVE'
AND B.date<A.date
GROUP BY A.date,A.user
Upvotes: 1