我在Oracle中有一个跟踪用户登录和注销/超时的表。我正在制作一个选择查询,以按小时显示过去7天的并发用户数。我有一个基本查询,但它没有正确计算会话跨越午夜的用户。
关于数据/我的查询的一些信息:
Attemptdate
是行动发生的时间Attemptresult7
是登录操作(LOGIN / LOGOUT / TIMEOUT)Maxsessionuid
是用户会话ID,可用于将登录与logout / timeout链接。- 到目前为止我的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?
答案 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