sql >> Database >  >> RDS >> Oracle

maak id-kolom op basis van activiteitsgegevens

Ik denk dat dit voldoende zal zijn:

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

Deze oplossing is gebaseerd op de logische kortsluiting die plaatsvindt in de CASE-expressie en het feit dat het event_type niet null is. Het gaat er ook van uit dat meerdere afmeldingen achter elkaar worden geteld als afzonderlijke sessies:

  1. Als de vorige rij een uitlogrij was (en als er geen vorige rij is - d.w.z. voor de eerste rij in de set - behandel deze alsof er een uitlogrij aanwezig was), willen we de teller met één verhogen. (Uitloggen beëindigen de sessie, dus we hebben altijd een nieuwe sessie na een uitloggen.)
  2. Als de huidige rij een afmelding is, wordt de bestaande sessie beëindigd. Daarom mag de teller niet worden verhoogd.
  3. Als de tijd van de huidige rij meer dan een uur verwijderd is van de vorige rij, verhoogt u de teller met één.
  4. Als de huidige rij een inlogrij is, dan is het een nieuwe sessie, dus verhoog de teller met één.
  5. Voor alle andere gevallen verhogen we de teller niet.

Als we dat eenmaal hebben gedaan, is het gewoon een kwestie van een lopend totaal op de teller.



  1. Hoe een enkele tabel in de mysql-database te importeren met behulp van de opdrachtregel

  2. Trigger-syntaxis en ALS ANDERS DAN

  3. MySQL/MariaDB Vault Database Secrets Engine inrichten met Terraform

  4. Alle id's opnemen in ActiveRecord-query