sql >> Databáze >  >> RDS >> Oracle

vytvořit sloupec id na základě údajů o aktivitě

Myslím, že tohle bude stačit:

WITH EVENTS AS (SELECT 'abc' usr, to_date('2016-01-01 08:00:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'login' event_type FROM dual UNION ALL
                SELECT 'abc' usr, to_date('2016-01-01 08:25:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'Stuff' event_type FROM dual UNION ALL
                SELECT 'abc' usr, to_date('2016-01-01 10:00:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'Stuff' event_type FROM dual UNION ALL
                SELECT 'abc' usr, to_date('2016-01-01 14:00:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'login' event_type FROM dual UNION ALL
                SELECT 'xyz' usr, to_date('2015-12-31 18:00:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'login' event_type FROM dual UNION ALL
                SELECT 'xyz' usr, to_date('2016-01-01 08:00:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'Logout' event_type FROM dual UNION ALL
                SELECT 'def' usr, to_date('2016-01-01 08:00:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'Logout' event_type FROM dual UNION ALL
                SELECT 'def' usr, to_date('2016-01-01 08:15:00', 'yyyy-mm-dd hh24:mi:ss') event_ts, 'Logout' event_type FROM dual)
SELECT usr,
       event_ts,
       event_type,
       SUM(counter) OVER (PARTITION BY usr ORDER BY event_ts) session_id
FROM   (SELECT usr,
               event_ts,
               event_type,
               CASE WHEN LAG(event_type, 1, 'Logout') OVER (PARTITION BY usr ORDER BY event_ts) = 'Logout' THEN 1
                    WHEN event_type = 'Logout' THEN 0
                    WHEN event_ts - LAG(event_ts) OVER (PARTITION BY usr ORDER BY event_ts) > 1/24 THEN 1
                    WHEN event_type = 'login' THEN 1
                    ELSE 0
               END counter
        FROM   EVENTS);

USR EVENT_TS            EVENT_TYPE SESSION_ID
--- ------------------- ---------- ----------
abc 2016-01-01 08:00:00 login               1
abc 2016-01-01 08:25:00 Stuff               1
abc 2016-01-01 10:00:00 Stuff               2
abc 2016-01-01 14:00:00 login               3
def 2016-01-01 08:00:00 Logout              1
def 2016-01-01 08:15:00 Logout              2
xyz 2015-12-31 18:00:00 login               1
xyz 2016-01-01 08:00:00 Logout              1

Toto řešení se opírá o logické zkratování, které probíhá ve výrazu CASE, a skutečnost, že typ_události není null. Také předpokládá, že více odhlášení v řadě se počítá jako samostatné relace:

  1. Pokud předchozí řádek byl odhlašovací řádek (a pokud neexistuje žádný předchozí řádek - tj. pro první řádek v sadě - zacházejte s ním, jako by byl přítomen odhlašovací řádek), chceme zvýšit počítadlo o jednu. (Odhlášení ukončí relaci, takže po odhlášení máme vždy novou relaci.)
  2. Pokud je aktuální řádek odhlášení, ukončí se tím stávající relace. Proto by se počítadlo nemělo zvyšovat.
  3. Pokud je čas aktuálního řádku větší než jedna hodina od předchozího řádku, zvyšte počítadlo o jednu.
  4. Pokud je aktuální řádek řádek pro přihlášení, jedná se o novou relaci, zvyšte tedy počítadlo o jednu.
  5. V žádném jiném případě počítadlo nezvyšujeme.

Jakmile to uděláme, jde jen o to udělat průběžný součet na počítadle.



  1. Jak vytvořit spouštěč pro odstranění php myadmin

  2. Jak vybrat konkrétní hodnoty z XML pomocí Oracle Xquery

  3. Connector/J MySQL driver v Jenkins Script Console / Scriptler

  4. Neočekávané výsledky MySQL:klauzule IN (číslo, 'řetězec') ve sloupci varchar