Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

buat kolom id berdasarkan data aktivitas

Saya pikir ini akan berhasil:

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

Solusi ini bergantung pada hubung singkat logika yang terjadi dalam ekspresi CASE dan fakta bahwa event_type tidak nol. Ini juga mengasumsikan bahwa beberapa logout berturut-turut dihitung sebagai sesi terpisah:

  1. Jika baris sebelumnya adalah baris keluar (dan jika tidak ada baris sebelumnya - yaitu untuk baris pertama dalam kumpulan - perlakukan seolah-olah ada baris keluar), kami ingin menambah penghitung satu per satu. (Logout mengakhiri sesi, jadi kami selalu memiliki sesi baru setelah logout.)
  2. Jika baris saat ini adalah logout, maka sesi yang ada akan dihentikan. Oleh karena itu, penghitung tidak boleh ditingkatkan.
  3. Jika waktu baris saat ini lebih besar dari satu jam dari baris sebelumnya, tambah penghitung satu per satu.
  4. Jika baris saat ini adalah baris login, maka ini adalah sesi baru, jadi tambah penghitungnya satu per satu.
  5. Untuk kasus lain, kami tidak menambah penghitung.

Setelah kami selesai melakukannya, tinggal melakukan total lari di konter.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. java.sql.SQLException:Pengecualian Io:Pipa rusak bagaimana memulihkan tanpa memulai ulang?

  2. Temukan kunci asing yang cocok dengan beberapa nilai baris

  3. buat sinonim ora-01031 hak istimewa yang tidak mencukupi

  4. mengapa kueri terlalu lama

  5. NetBeans IDE di bawah Oracle