Pelajaran modul (3/4)
LAG, LEAD dan total berjalan
LAG dan LEAD adalah dua fungsi jendela khusus yang memberi Anda akses ke
baris lain dari partisi yang sama: baris sebelumnya (LAG) atau
berikutnya (LEAD) sesuai dengan ORDER BY jendela. Mereka adalah
alat bantu untuk perbandingan baris ke baris (delta, variasi, interval)
dan — digabungkan dengan SUM/AVG/COUNT OVER — untuk total berjalan.
LAG: baris sebelumnya
LAG(colonna) OVER (PARTITION BY p ORDER BY o)
LAG(colonna, n) OVER (PARTITION BY p ORDER BY o) -- n righe indietro
LAG(colonna, n, default) OVER (PARTITION BY p ORDER BY o) -- default se non c'èContoh: untuk setiap pesanan, "hari sejak pesanan sebelumnya sama pelanggan":
SELECT id,
customer_id,
ordered_at,
ordered_at - LAG(ordered_at) OVER (
PARTITION BY customer_id ORDER BY ordered_at
) AS since_previous_order
FROM orders
ORDER BY customer_id, ordered_at;Setiap pesanan pertama pelanggan memiliki since_previous_order = NULL karena
tidak ada "sebelumnya" di partisi.
LEAD: baris berikutnya
Cermin LAG. Khas: "waktu hingga kejadian berikutnya", "perbedaan
dengan versi selanjutnya".
SELECT id, ordered_at,
LEAD(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at)
- ordered_at AS to_next
FROM orders;Total berjalan: agregat dengan OVER
Fungsi agregat (SUM, AVG, COUNT, MAX, MIN) menjadi
kumulatif bila digabungkan dengan OVER (… ORDER BY …):
SELECT order_id,
total,
SUM(total) OVER (
PARTITION BY customer_id
ORDER BY ordered_at
) AS running_total
FROM …;Untuk setiap baris, SUM menghitung jumlah semua baris di partisi hingga
saat itu, menurut ORDER BY jendela. Hasilnya adalah
klasik "keseimbangan berjalan".
Cobalah
Untuk setiap pesanan tampilkan id, id_pelanggan, id_pelanggan, dan kolom hari_dari_sebelumnya yang merupakan jumlah hari penuh (dengan LANTAI) antara pesanan saat ini dan pesanan sebelumnya dari pelanggan yang sama, dipesan berdasarkan pesanan_at. NULL jika tidak ada pesanan sebelumnya. Pesan berdasarkan id_pelanggan dan dipesan_at.
Tunjukkan petunjuk
LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BY order_at) mengembalikan stempel waktu pesanan pelanggan sebelumnya. Kurangi untuk mendapatkan INTERVAL, lalu konversikan menjadi hari.
Solusi tersedia setelah 3 upaya
Tinjau latihan
Untuk setiap pesanan yang terkirim (status = 'terkirim'), tampilkan id, customer_id, order_at, order_total (jumlah kuantitas * unit_price item barisnya) dan running_total (total berjalan dari total per pelanggan, dipesan berdasarkan pesanan_at). Gunakan CTE untuk order_total. Pesan berdasarkan id_pelanggan dan dipesan_at.
Tunjukkan petunjuk
CTE menghitung total per pesanan; SUM OVER menghasilkan total berjalan per pelanggan dari waktu ke waktu.
Solusi tersedia setelah 3 upaya