查询建议需要

时间:2017-03-12 13:32:29

标签: sql oracle

我有一个表,用于管理计算机上的用户登录。根据活动类型,我确定它是登录还是注销。我被要求生成有关用户登录/注销的报告。它适用于所有班次,但不适用于午夜班次。

样本表:

User_id Activity_code timestamp
1       login         2016-03-28 11:10:00
1       logout        2016-03-28 19:45:00
2       login         2017-02-15 23:00:00
2       logout        2017-02-16 07:00:00

如果我按时间戳分组,我会为用户id1正确获取报告,但不会为用户2报告。

desc pmevents_bkp

 Name           Null?    Type
 -------------  -------  --------------
 EVENTTYPE      NOT NULL  NUMBER(4)
 USERID                   CHAR(32)
 JOBNUMBER                NUMBER(11)
 TIMESTAMP      NOT NULL  DATE
 SEQUENCENUMBER           NUMBER(8)

 SQL >select * from pmevents_bkp;

 EVENTTYPE USERID                            JOBNUMBER TIMESTAMP SEQUENCENUMBER
---------- -------------------------------- ---------- --------- --------------
       101 JBOND 007                             12345 11-MAR-17          12345
       101 JBOND 007                             12345 12-MAR-17          12345
       101 JBOND 008                              3245 11-MAR-17           3245
       100 JBOND 007                             12345 11-MAR-17           3245

 SQL >select to_char(timestamp, 'MM/DD/YYYY'),
    2  userid,
    3  MIN(timestamp) KEEP (DENSE_RANK FIRST ORDER BY eventtype) "Login",
    4  MAX(timestamp) KEEP (DENSE_RANK LAST ORDER BY eventtype) "Logout"
    5     FROM pmevents_bkp
    6     where  timestamp BETWEEN TO_DATE('01-mar-17','DD-MON-YY') AND TO_DATE('30-mar-17','DD-MON-YY')
    7  and (eventtype = '100'
    8  or eventtype = '101')
    9  group by to_char(timestamp, 'MM/DD/YYYY'),userid;

TO_CHAR(TI USERID                           Login     Logout
---------- -------------------------------- --------- ---------
03/11/2017 JBOND 007                        11-MAR-17 11-MAR-17
03/11/2017 JBOND 008                        11-MAR-17 11-MAR-17
03/12/2017 JBOND 007                        12-MAR-17 12-MAR-17

2 个答案:

答案 0 :(得分:0)

无论是每天多次登录/退出还是缺少注销,这都有效:

select *
from 
 (
    select User_id, 

       -- login timestamp
       case when Activity_code = 'login' then timestamp end as Login,

       -- next row's timestamp (only if it's a logout)
       lead(case when Activity_code = 'logout' then timestamp end) 
       over (partition by User_id 
             order by timestamp) as Logout
    from tab
 ) dt
where Logon is not null -- only the login rows

答案 1 :(得分:0)

@dnoeth:

select to_char(timestamp, 'MM/DD/YYYY'),
userid,
MIN(timestamp) KEEP (DENSE_RANK FIRST ORDER BY eventtype) "Login",
MAX(timestamp) KEEP (DENSE_RANK LAST ORDER BY eventtype) "Logout"
FROM formscan.pmevents_bkp
where  timestamp BETWEEN TO_DATE('01-mar-17','DD-MON-YY') AND TO_DATE('30-      
mar-17','DD-MON-YY')
and (eventtype = '100'
or eventtype = '101')
group by to_char(timestamp, 'MM/DD/YYYY'),userid;