并发用户报告

时间:2013-10-28 15:53:39

标签: sql oracle maximo

我在Oracle中有一个跟踪用户登录和注销/超时的表。我正在制作一个选择查询,以按小时显示过去7天的并发用户数。我有一个基本查询,但它没有正确计算会话跨越午夜的用户。

关于数据/我的查询的一些信息:

  • Logintracking保存所有用户登录操作,例如登录/注销/超时操作。每个动作都在一个单独的行上。
  • Attemptdate是行动发生的时间
  • Attemptresult7是登录操作(LOGIN / LOGOUT / TIMEOUT)
  • 的结果
  • Maxsessionuid是用户会话ID,可用于将登录与logout / timeout链接。
  • 我正在使用左外部自联接来根据会话ID匹配登录和注销。由于用户可能仍然登录,因此我用sysdate替换空注销日期。
  • 我按年/月/日对数据进行分组,并删除用户可能已使用distinct登录两次的所有记录。登录10次的同一用户在此报告中仅被视为1个并发用户。 (这部分也没有真正起作用,因为我的不同之处在于登录和注销时间,会话之间可能会有所不同。我真的需要为同一个用户组合重叠会话......)
  • 我通过查看0到23之间的每小时是否在他们的登录和注销之间来计算并发用户数(当然这对于跨越几天的会话不起作用)

- 到目前为止我的Oracle查询:

Select Lyear,
        Lmonth,
        Lday,
        Sum(Case When 0 Between Lhour And Ohour Then 1 Else 0 End) H00,
        Sum(CASE WHEN 1 between LHour and OHour Then 1 Else 0 End) H01,
        Sum(CASE WHEN 2 between LHour and OHour Then 1 Else 0 End) H02,
        Sum(Case When 3 Between Lhour And Ohour Then 1 Else 0 End) H03,
        Sum(CASE WHEN 4 between LHour and OHour Then 1 Else 0 End) H04,
        Sum(CASE WHEN 5 between LHour and OHour Then 1 Else 0 End) H05,
        Sum(CASE WHEN 6 between LHour and OHour Then 1 Else 0 End) H06,
        Sum(CASE WHEN 7 between LHour and OHour Then 1 Else 0 End) H07,
        Sum(CASE WHEN 8 between LHour and OHour Then 1 Else 0 End) H08,
        Sum(Case When 9 Between Lhour And Ohour Then 1 Else 0 End) H09,
        Sum(CASE WHEN 10 between LHour and OHour Then 1 Else 0 End) H10,
        Sum(CASE WHEN 11 between LHour and OHour Then 1 Else 0 End) H11,
        Sum(CASE WHEN 12 between LHour and OHour Then 1 Else 0 End) H12,
        Sum(CASE WHEN 13 between LHour and OHour Then 1 Else 0 End) H13,
        Sum(CASE WHEN 14 between LHour and OHour Then 1 Else 0 End) H14,
        Sum(CASE WHEN 15 between LHour and OHour Then 1 Else 0 End) H15,
        Sum(Case When 16 Between Lhour And Ohour Then 1 Else 0 End) H16,
        Sum(Case When 17 Between Lhour And Ohour Then 1 Else 0 End) H17,
        Sum(Case When 18 Between Lhour And Ohour Then 1 Else 0 End) H18,
        Sum(CASE WHEN 19 between LHour and OHour Then 1 Else 0 End) H19,
        Sum(Case When 20 Between Lhour And Ohour Then 1 Else 0 End) H20,
        Sum(Case When 21 Between Lhour And Ohour Then 1 Else 0 End) H21,
        Sum(CASE WHEN 22 between LHour and OHour Then 1 Else 0 End) H22,
        Sum(Case When 23 Between Lhour And Ohour Then 1 Else 0 End) H23
From (    
Select Distinct L1.Userid,
         Extract(Year From L1.Attemptdate) Lyear,  
         Extract(Month From L1.Attemptdate) Lmonth, 
         Extract(Day From L1.Attemptdate) Lday,
    --You can't extract HOUR from a date, must be a timestamp
         Extract(Hour From Cast(L1.Attemptdate As Timestamp)) As Lhour, 
         Extract(Hour From Cast(NVL(L2.Attemptdate,SYSDATE) As Timestamp)) As OHour
  From Maximo.Logintracking L1
        LEFT OUTER JOIN Maximo.Logintracking L2 On
          L1.Maxsessionuid = L2.Maxsessionuid
  Where L1.Attemptresult7 = 'LOGIN' And L2.Attemptresult7 != 'LOGIN'
        And L1.Attemptdate > Trunc( Sysdate)-7
        And L2.Attemptdate > Trunc(Sysdate)-7) Sessions
Group By Lyear, Lmonth, Lday    
ORDER By LYear, LMonth, LDay

查询不必保留现在的状态。但最终结果应该是我按小时查看并发用户的x天视图。

相关:How to count the number of concurrent users using time interval data?

1 个答案:

答案 0 :(得分:1)

在某个地方,我的简单整齐的书面查询变成了这个怪物(似乎有效,至少对它有好处):

CREATE TABLE logintracking (
  userid NUMBER,
  maxsessionuid NUMBER,
  Attemptdate DATE,
  attemptresult7 VARCHAR2(20)
);

INSERT INTO logintracking VALUES (1, 100, TO_DATE('27-10-2013 10:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 100, TO_DATE('27-10-2013 12:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (1, 101, TO_DATE('27-10-2013 11:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 101, TO_DATE('27-10-2013 15:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (1, 102, TO_DATE('27-10-2013 23:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 102, TO_DATE('28-10-2013 02:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (1, 103, TO_DATE('27-10-2013 20:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 103, TO_DATE('28-10-2013 01:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (2, 104, TO_DATE('27-10-2013 23:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (2, 104, TO_DATE('28-10-2013 02:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

COMMIT;

WITH
  hours_of_last_7_days AS (
    SELECT TRUNC(SYSDATE, 'HH24') - numtodsinterval(level, 'HOUR') AS hour_val
      FROM dual
    CONNECT BY level <= 7 * 24
  )
SELECT
    lyear,
    lmonth,
    lday,
    SUM(DECODE(lhour, 0, 1, 0)) AS H00,
    SUM(DECODE(lhour, 1, 1, 0)) AS H01,
    SUM(DECODE(lhour, 2, 1, 0)) AS H02,
    SUM(DECODE(lhour, 3, 1, 0)) AS H03,
    SUM(DECODE(lhour, 4, 1, 0)) AS H04,
    SUM(DECODE(lhour, 5, 1, 0)) AS H05,
    SUM(DECODE(lhour, 6, 1, 0)) AS H06,
    SUM(DECODE(lhour, 7, 1, 0)) AS H07,
    SUM(DECODE(lhour, 8, 1, 0)) AS H08,
    SUM(DECODE(lhour, 9, 1, 0)) AS H09,
    SUM(DECODE(lhour, 10, 1, 0)) AS H10,
    SUM(DECODE(lhour, 11, 1, 0)) AS H11,
    SUM(DECODE(lhour, 12, 1, 0)) AS H12,
    SUM(DECODE(lhour, 13, 1, 0)) AS H13,
    SUM(DECODE(lhour, 14, 1, 0)) AS H14,
    SUM(DECODE(lhour, 15, 1, 0)) AS H15,
    SUM(DECODE(lhour, 16, 1, 0)) AS H16,
    SUM(DECODE(lhour, 17, 1, 0)) AS H17,
    SUM(DECODE(lhour, 18, 1, 0)) AS H18,
    SUM(DECODE(lhour, 19, 1, 0)) AS H19,
    SUM(DECODE(lhour, 20, 1, 0)) AS H20,
    SUM(DECODE(lhour, 21, 1, 0)) AS H21,
    SUM(DECODE(lhour, 22, 1, 0)) AS H22,
    SUM(DECODE(lhour, 23, 1, 0)) AS H23
  FROM (
    SELECT
      DISTINCT
          sessions.userid,
          EXTRACT(YEAR FROM hour_val) AS lyear,
          EXTRACT(MONTH FROM hour_val) AS lmonth,
          EXTRACT(DAY FROM hour_val) AS lday,
          EXTRACT(HOUR FROM CAST(hour_val AS TIMESTAMP)) AS lhour
        FROM (
            SELECT start_lt.userid, start_lt.attemptdate AS login_date, NVL(end_lt.attemptdate, sysdate) AS logout_date
              FROM
                logintracking start_lt
                  LEFT OUTER JOIN logintracking end_lt  ON (start_lt.maxsessionuid = end_lt.maxsessionuid AND start_lt.attemptresult7 <> end_lt.attemptresult7)
            WHERE
              start_lt.attemptresult7 = 'LOGIN'
              AND start_lt.attemptdate > Trunc(SYSDATE) - 8
          ) sessions
          JOIN hours_of_last_7_days hd ON (hd.hour_val BETWEEN trunc(sessions.login_date,'HH24') AND trunc(sessions.logout_date,'HH24'))
  )
GROUP BY lyear, lmonth, lday
ORDER BY lyear, lmonth, lday
;

输出:

     LYEAR     LMONTH       LDAY        H00        H01        H02        H03        H04        H05        H06        H07        H08        H09        H10        H11        H12        H13        H14        H15        H16        H17        H18        H19        H20        H21        H22        H23
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
      2013         10         27          0          0          0          0          0          0          0          0          0          0          1          1          1          1          1          1          0          0          0          0          1          1          1          2 
      2013         10         28          2          2          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0