测试表/数据:
drop table if exists a_table;
create table a_table (seq serial primary key, userid int, action text, created timestamp);
create index a_table_i on a_table (userid, action, created);
insert into a_table (userid, action, created) values
(1, 'ON' , '2016-01-10 12:00'),
(1, 'OFF' , '2016-01-10 17:00'),
(1, 'ON' , '2016-01-11 10:00'),
(1, 'OFF' , '2016-01-11 11:00'),
(1, 'ON' , '2016-01-11 20:00'),
(1, 'ON' , '2016-01-11 21:00'), -- an "ON" without an "OFF"
(1, 'OFF' , '2016-01-11 21:00'),
(1, 'OFF' , '2016-01-11 22:00'), -- an "OFF" without an "ON"
(1, 'ON' , '2016-01-11 21:10'),
(1, 'ON' , '2016-01-11 21:20'), -- an "ON" without an "OFF"
(1, 'OFF' , '2016-01-11 21:30'),
(2, 'ON' , '2016-01-10 13:00'),
(2, 'OFF' , '2016-01-10 15:00'),
(2, 'ON' , '2016-01-11 13:00'),
(2, 'OFF' , '2016-01-12 15:00');
查询表,记住可以存在许多“ON”用户操作而没有任何“OFF”(反之亦然):
SELECT USERID, SUM(FINISHED - CREATED) AS ACTIVE_TIME
FROM (
SELECT *,
-- GET THE NEXT 'OFF' ACTION RIGTH AFTER IT
COALESCE((SELECT CREATED FROM a_table T1 WHERE T1.USERID = T.USERID AND T1.SEQ > T.SEQ ORDER BY T1.SEQ LIMIT 1),CURRENT_TIMESTAMP) AS FINISHED
FROM a_table T
-- LIST ONLY RECORDS WHERE ACTION IS 'ON' AND THE USER'S ACTION RIGHT BEFORE WAS 'OFF' OR 'NONE'
WHERE ACTION = 'ON'
AND COALESCE((SELECT ACTION FROM a_table T1 WHERE T1.USERID = T.USERID AND T1.SEQ < T.SEQ ORDER BY T1.SEQ DESC LIMIT 1),'OFF') = 'OFF'
) A
GROUP BY USERID
结果:
userid active_time
1 07:10:00
2 1 day 04:00:00