Direct naar de hoofdinhoud
Module 7 · Les 3 van 427/57 in de cursus~12 min
Modulelessen (3/4)

LAG, LEAD en lopende totalen

LAG en LEAD zijn twee speciale vensterfuncties die u toegang geven tot andere rijen van dezelfde partitie: de vorige rij (LAG) of de volgende (LEAD) volgens ORDER BY van het venster. Zij zijn de go-to-tool voor rij-tot-rij-vergelijkingen (delta's, variaties, intervallen) en — gecombineerd met SUM/AVG/COUNT OVER — voor lopende totalen.

LAG: de vorige rij

SQL
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'è

Voorbeeld: voor elke bestelling, "dagen sinds de vorige bestelling hetzelfde klant":

SQL
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;

De eerste bestelling van elke klant heeft since_previous_order = NULL omdat er is geen "vorige" in de partitie.

LEID: de volgende rij

De spiegel van LAG. Typisch: "tijd tot de volgende gebeurtenis", "verschil met de volgende versie".

SQL
SELECT id, ordered_at,
       LEAD(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at)
         - ordered_at AS to_next
FROM   orders;

Lopende totalen: aggregeert met OVER

Geaggregeerde functies (SUM, AVG, COUNT, MAX, MIN) worden cumulatief in combinatie met OVER (… ORDER BY …):

SQL
SELECT order_id,
       total,
       SUM(total) OVER (
         PARTITION BY customer_id
         ORDER BY     ordered_at
       ) AS running_total
FROM   …;

Voor elke rij berekent SUM de som van alle rijen in de partitie tot dat punt, volgens de ORDER BY van het venster. Het resultaat is de klassieke "loopbalans".

Probeer het

Oefening#sql.m7.l3.e1
Pogingen: 0Laden…

Voor elke bestelling worden ID, klant_id, besteld_at en een kolom days_from_previous weergegeven. Dit is het aantal hele dagen (met FLOOR) tussen de huidige bestelling en de vorige van dezelfde klant, besteld door orderd_at. NULL als er geen eerdere bestelling is. Bestel op klant_id en besteld_at.

Editor laden…
Toon hint

LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at) retourneert de tijdstempel van de vorige bestelling van de klant. Trek dit af om een ​​INTERVAL te krijgen en converteer het vervolgens naar dagen.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#sql.m7.l3.e2
Pogingen: 0Laden…

Voor elke geleverde bestelling (status = 'geleverd') toont u id, customer_id, order_at, order_total (som van hoeveelheid * eenheidsprijs van de regelitems) en running_total (lopend totaal van de totalen per klant, besteld door order_at). Gebruik een CTE voor order_total. Bestel op klant_id en besteld_at.

Editor laden…
Toon hint

De CTE berekent het totaal per bestelling; de SOM OVER levert het lopende totaal per klant in de loop van de tijd op.

Oplossing beschikbaar na 3 pogingen