PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Fungsi lead/lag bersyarat PostgreSQL?

Definisi Anda:

kegiatan dari kelompok B selalu dilakukan setelah kegiatan dari kelompok A.

.. secara logis menyiratkan bahwa ada, per pengguna, 0 atau 1 aktivitas B setelah 1 atau lebih aktivitas A. Tidak pernah lebih dari 1 aktivitas B secara berurutan.

Anda dapat membuatnya bekerja dengan satu fungsi jendela, DISTINCT ON dan CASE , yang seharusnya menjadi cara tercepat untuk sedikit baris per pengguna (lihat juga di bawah):

SELECT name
     , CASE WHEN a2 LIKE 'B%' THEN a1 ELSE a2 END AS activity
     , CASE WHEN a2 LIKE 'B%' THEN a2 END AS next_activity
FROM  (
   SELECT DISTINCT ON (name)
          name
        , lead(activity) OVER (PARTITION BY name ORDER BY time DESC) AS a1
        , activity AS a2
   FROM   t
   WHERE (activity LIKE 'A%' OR activity LIKE 'B%')
   ORDER  BY name, time DESC
   ) sub;

db<>main biola di sini

SQL CASE ekspresi default ke NULL jika tidak ada ELSE cabang ditambahkan, jadi saya membuatnya singkat.

Dengan asumsi time didefinisikan NOT NULL . Jika tidak, Anda mungkin ingin menambahkan NULLS LAST . Mengapa?

  • Urutkan menurut kolom ASC, tetapi nilai NULL terlebih dahulu?

(activity LIKE 'A%' OR activity LIKE 'B%') lebih verbose daripada activity ~ '^[AB]' , tetapi biasanya lebih cepat di versi Postgres yang lebih lama. Tentang pencocokan pola:

  • Pencocokan pola dengan LIKE, SIMILAR TO atau ekspresi reguler di PostgreSQL

Fungsi jendela bersyarat?

Itu sebenarnya mungkin . Anda dapat menggabungkan agregat FILTER klausa dengan OVER klausa fungsi jendela. Namun :

  1. FILTER klausa itu sendiri hanya dapat bekerja dengan nilai dari baris saat ini.

  2. Lebih penting lagi, FILTER tidak diimplementasikan untuk fungsi asli murni seperti lead() atau lag() (hingga Postgres 13) - hanya untuk fungsi agregat.

Jika Anda mencoba:

lead(activity) FILTER (WHERE activity LIKE 'A%') OVER () AS activity

Postgres akan memberi tahu Anda:

FILTER is not implemented for non-aggregate window functions

Tentang FILTER :

  • Kolom gabungan dengan filter tambahan (berbeda)
  • Mereferensikan baris saat ini dalam klausa FILTER dari fungsi jendela

Kinerja

Untuk sedikit pengguna dengan sedikit baris per pengguna, cukup banyak apa saja kueri cepat, bahkan tanpa indeks.

Untuk banyak pengguna dan sedikit baris per pengguna, kueri pertama di atas harus tercepat. Lihat:

  • Pilih baris pertama di setiap grup GROUP BY?

Untuk banyak baris per pengguna, ada (berpotensi banyak ) teknik yang lebih cepat, tergantung pada detail penyiapan Anda. Lihat:

  • Optimalkan kueri GROUP BY untuk mengambil baris terbaru per pengguna


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Penggabungan Koneksi PostgreSQL:Bagian 3 – Pgpool-II

  2. Bagaimana cara membuat Tampilan SQL dengan SQLAlchemy?

  3. Berhenti (lama) menjalankan kueri SQL di PostgreSQL saat sesi atau permintaan tidak ada lagi?

  4. SELECT memunculkan pengecualian dalam fungsi PL/pgSQL

  5. Pagination Django Rest Framework hitungannya sangat lambat