Kumulativa summor med fönsterramar
Skapa en löpande totalsumma med SUM OVER och en sorterad ram
Kumulativa summor med fönsterramar är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Förberedelse inför kodningsintervjuer, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.
Frågan om löpande totalsummor
Nästan varje intervju för analytiker innehåller någon variant av: "Visa de kumulativa intäkterna över tid." En löpande totalsumma är en summa som växer rad för rad och ackumulerar allt från början fram till den aktuella raden.
Innan fönsterfunktioner fanns löste kandidater detta med en långsam self-join eller en korrelerad underfråga. Det moderna, förväntade svaret är SUM(...) OVER (ORDER BY ...). Om du känner till versionen med en fönsterram visar det att du förstår SQL som skrivits efter ungefär 2012.
Anatomin hos en ordnad fönstersumma
En löpande totalsumma är helt enkelt ett aggregat som omvandlats till en fönsterfunktion. Du behåller SUM(amount) men lägger till en OVER-klausul med en ORDER BY.
Det är ORDER BY inuti OVER som gör summan kumulativ: den anger för SQL att raderna ska ackumuleras i den ordningen. Utan en ORDER BY skulle SUM summera hela partitionen för varje rad i stället för att växa.
SELECT
sale_date,
amount,
SUM(amount) OVER (ORDER BY sale_date) AS running_total
FROM sales
ORDER BY sale_date;Varför ORDER BY innebär en ram
Här är detaljen som intervjuare gärna undersöker: när du lägger till ORDER BY i ett fönsteraggregat använder SQL en standardram på RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
Det är precis denna standardram som skapar en löpande totalsumma: varje rad från partitionens början till och med den aktuella raden. Om du förstår denna standardinställning förstår du varför den kumulativa summan "bara fungerar".
Gör ramen uttrycklig
Du kan skriva ut ramen manuellt. De här två frågorna returnerar samma resultat, men den uttryckliga versionen visar intervjuaren att du förstår vad som sker under huven.
Att skriva ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW är den säkraste uttryckliga formen för en löpande totalsumma eftersom den räknar fysiska rader och undviker överraskningarna med värdegruppering i RANGE (som tas upp i nästa lektion).
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM sales;Genomgångsexempel: Daglig försäljning
Föreställ dig fyra försäljningsdagar: mån 100, tis 50, ons 200, tors 75. Den löpande totalsumman ackumuleras från vänster till höger.
- Mån: 100
- Tis: 100 + 50 = 150
- Ons: 150 + 200 = 350
- Tors: 350 + 75 = 425
Den sista raden är alltid lika med totalsumman. Det är en snabb rimlighetskontroll som du kan nämna i en intervju: det sista värdet i den löpande totalsumman måste motsvara SUM(amount) för hela mängden.
Återställning per grupp med PARTITION BY
Verkliga frågor efterfrågar vanligtvis en löpande totalsumma per kund eller per region, inte en enda global totalsumma. Lägg till PARTITION BY, så börjar ackumuleringen om i början av varje partition.
En användbar mental modell är att PARTITION BY delar upp raderna i oberoende grupper, medan ORDER BY och ramen körs separat inom varje grupp.
SELECT
customer_id,
sale_date,
amount,
SUM(amount) OVER (
PARTITION BY customer_id
ORDER BY sale_date
) AS customer_running_total
FROM sales;Fallgropen med lika värden
Om två rader har samma ORDER BY-värde (två försäljningar samma dag) behandlar standardramen RANGE dem som peers och ger dem samma löpande totalsumma, inklusive båda beloppen.
Om du behöver en strikt ökning rad för rad även vid lika värden byter du till ramen ROWS och lägger till en unik tiebreaker i ORDER BY, till exempel sale_date, id. Intervjuare lägger specifikt in dubblettdatum för att se om du uppmärksammar detta.
SELECT
sale_date,
amount,
SUM(amount) OVER (
ORDER BY sale_date, id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM sales;Löpande antal
Kumulativ logik är inte begränsad till SUM. Alla aggregat fungerar som fönsterfunktioner, så du kan skapa ett löpande antal, ett löpande medelvärde eller ett löpande maximum.
Ett löpande antal beställningar är ett vanligt mått i instrumentpaneler: hur många beställningar har tagits emot hittills fram till varje dag?
SELECT
order_date,
COUNT(*) OVER (
ORDER BY order_date
) AS orders_to_date
FROM orders;Det gamla sättet: korrelerad underfråga
Intervjuare ber dig ibland lösa en löpande totalsumma utan fönsterfunktioner för att testa din förståelse på djupet. Den klassiska lösningen från tiden före fönsterfunktioner är en korrelerad underfråga som summerar om alla tidigare rader.
Det fungerar, men har komplexiteten O(n²): för varje rad läses tabellen igen. Nämn detta för att visa att du vet varför fönsterfunktioner ersatte lösningen.
SELECT
s.sale_date,
s.amount,
(SELECT SUM(s2.amount)
FROM sales s2
WHERE s2.sale_date <= s.sale_date) AS running_total
FROM sales s
ORDER BY s.sale_date;Filtrering kontra fönsterresultatet
En vanlig följdfråga är: "Visa endast dagar då den löpande totalsumman passerade 1000." Du kan inte placera en fönsterfunktion i WHERE eftersom ramen beräknas efter att WHERE har körts.
Lösningen är att beräkna den löpande totalsumman i en CTE eller underfråga och sedan filtrera i den yttre frågan. Det är samma regel om att kapsla in resultatet som gäller för alla fönsterfunktioner.
WITH t AS (
SELECT
sale_date,
SUM(amount) OVER (ORDER BY sale_date) AS running_total
FROM sales
)
SELECT *
FROM t
WHERE running_total >= 1000;Viktiga punkter inför intervjun
När du presenterar en lösning med löpande totalsumma bör du ta upp följande punkter för att få full poäng:
SUM OVER (ORDER BY ...)är den kumulativa formen.- Att lägga till
ORDER BYskapar en standardram frånUNBOUNDED PRECEDINGtillCURRENT ROW. - Använd
PARTITION BYför att återställa beräkningen per grupp. - Lägg till en unik tiebreaker och ramtypen
ROWSför att undvika fallgropen med lika värden. - Kapsla in beräkningen i en CTE för att kunna filtrera på resultatet.
Snabb kontroll
Testa din förståelse av standardramen.
Sammanfattning: Kumulativa summor
En löpande totalsumma är ett ordnat fönsteraggregat. SUM(amount) OVER (ORDER BY sale_date) ackumulerar rader från partitionens början till den aktuella raden tack vare den implicita ramen från UNBOUNDED PRECEDING till CURRENT ROW.
Återställ den per grupp med PARTITION BY, lägg till en tiebreaker tillsammans med ramen ROWS för att hantera dubbletter i sorteringsvärden och kapsla in beräkningen i en CTE när du behöver filtrera på det kumulativa värdet. I nästa lektion går vi igenom skillnaden mellan ROWS och RANGE som den här lektionen introducerade.
Lär dig Förberedelse inför kodningsintervjuer med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 90
- Lektioner
- 360
Vanliga frågor
Är lektionen ”Kumulativa summor med fönsterramar” gratis?
Ja – hela texten till ”Kumulativa summor med fönsterramar” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Förberedelse inför kodningsintervjuer, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.
Vad lär jag mig i ”Kumulativa summor med fönsterramar”?
Skapa en löpande totalsumma med SUM OVER och en sorterad ram Ni övar på Förberedelse inför kodningsintervjuer med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Förberedelse inför kodningsintervjuer?
Du behöver inga förkunskaper. Utbildningen i Förberedelse inför kodningsintervjuer på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Kumulativa summor med fönsterramar”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Förberedelse inför kodningsintervjuer-lektionen?
Ja. Varje Förberedelse inför kodningsintervjuer-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Kumulativa summor med fönsterramar
- ROWS kontra RANGE som ram
- Glidande medelvärden över ett rullande fönster
- Kumulativ fördelning och andel av totalen