Förberedelser inför SQL-intervjun · Lektion

N på varandra följande rader som uppfyller ett villkor

Det klassiska fönstermönstret ”tre dagar i rad med försäljning över X”.

Lektion 3 av 413 steg

N på varandra följande rader som uppfyller ett villkor är en gratis lektion i Förberedelser inför SQL-intervjun på CoddyKit. Detta är lektion 3 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örberedelser inför SQL-intervjun, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelser inför SQL-intervjun innehåller totalt 4 lektioner.

En LeetCode-klassiker

Det här är en av de vanligaste SQL-frågorna på intervjuer: "Hitta alla datum med minst tre på varandra följande dagar då försäljningen översteg ett tröskelvärde," eller LeetCode-favoriten "rapportera arenan med 3+ på varandra följande rader där antalet besökare översteg 100."

Strukturen är alltid densamma: en rad uppfyller villkoret endast om den ingår i en följd av N på varandra följande rader som uppfyller villkoret. I den här lektionen visas två tydliga lösningar och den fallgrop som fångar de flesta kandidater.

Exempeldata

Vi använder en daglig sales-tabell. Villkoret är amount > 100. Vi måste returnera varje dag som ingår i en följd av minst 3 på varandra följande kalenderdagar där alla uppfyller villkoret.

  • sale_date — en rad per dag
  • amount — den totala försäljningen den dagen

En viktig detalj är att raderna måste vara sammanhängande i ordningsföljden och, i datumvarianter, även på kalendern.

SELECT * FROM sales ORDER BY sale_date;
-- sale_date  | amount
-- 2024-03-01 |  120
-- 2024-03-02 |  150
-- 2024-03-03 |  130
-- 2024-03-04 |   90
-- 2024-03-05 |  200

Metod 1: Filtrera och bilda öar

Den robusta metoden är att först behålla endast rader som uppfyller villkoret, sedan gruppera de återstående raderna i sammanhängande öar och slutligen behålla öar vars längd är minst N.

Det första steget är WHERE-filtret. I det andra steget återanvänds ankaret från metoden med luckor och öar. Eftersom vi filtrerade först betyder en ö här en följd av på varandra följande dagar som uppfyller villkoret.

WITH qualifying AS (
  SELECT sale_date
  FROM sales
  WHERE amount > 100
)
SELECT * FROM qualifying ORDER BY sale_date;

Förankra följderna som uppfyller villkoret

Numrera raderna som uppfyller villkoret efter datum och subtrahera för att få öns ankare. Rader som ligger efter varandra i kalendern OCH alla uppfyller villkoret får samma ankare. Dagar som inte uppfyller villkoret har tagits bort, vilket bryter följden exakt där den ska brytas.

WITH qualifying AS (
  SELECT sale_date
  FROM sales
  WHERE amount > 100
),
numbered AS (
  SELECT sale_date,
    ROW_NUMBER() OVER (ORDER BY sale_date) AS rn
  FROM qualifying
)
SELECT sale_date, sale_date - rn AS grp
FROM numbered;

Behåll tillräckligt långa öar

Gruppera efter ankaret, räkna raderna och behåll endast grupper med COUNT(*) >= 3. Om intervjuaren vill ha tillbaka de enskilda datumen som uppfyller villkoret, kopplar ni de behållna ankarna till de numrerade raderna.

WITH qualifying AS (
  SELECT sale_date FROM sales WHERE amount > 100
),
numbered AS (
  SELECT sale_date,
    ROW_NUMBER() OVER (ORDER BY sale_date) AS rn
  FROM qualifying
),
islands AS (
  SELECT sale_date - rn AS grp, COUNT(*) AS len
  FROM numbered
  GROUP BY sale_date - rn
  HAVING COUNT(*) >= 3
)
SELECT n.sale_date
FROM numbered n
JOIN islands i ON n.sale_date - n.rn = i.grp
ORDER BY n.sale_date;

Metod 2: Glidande COUNT-fönster

En smidigare metod när N är litet och fast är att använda en fönsterram för att räkna hur många av de omgivande raderna som också uppfyller villkoret. Om något fönster med N på varandra följande rader som innehåller den här raden helt uppfyller villkoret, ingår raden i resultatet.

Lägg först till en boolesk flagga och summera sedan flaggan över glidande fönsterramar.

SELECT sale_date, amount,
  CASE WHEN amount > 100 THEN 1 ELSE 0 END AS ok
FROM sales;

Summera över tre ramar

För en följd på exakt 3 ingår en rad som uppfyller villkoret i resultatet om fönstret med 3 rader som slutar här, är centrerat här eller börjar här summerar till 3. Beräkna de tre rullande summorna och kontrollera om någon av dem är lika med 3.

Det här är tekniken bakom lösningen på LeetCode 601 (Human Traffic of Stadium).

WITH flagged AS (
  SELECT sale_date, amount,
    CASE WHEN amount > 100 THEN 1 ELSE 0 END AS ok
  FROM sales
),
w AS (
  SELECT *,
    SUM(ok) OVER (ORDER BY sale_date
      ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS s_end,
    SUM(ok) OVER (ORDER BY sale_date
      ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS s_mid,
    SUM(ok) OVER (ORDER BY sale_date
      ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) AS s_start
  FROM flagged
)
SELECT sale_date, amount
FROM w
WHERE ok = 1 AND (s_end = 3 OR s_mid = 3 OR s_start = 3);

Fallgropen med luckor i kalendern

Metoden med fönstersummor använder ROWS, som räknar intilliggande resultatrader, inte intilliggande kalenderdagar. Om en dag som inte uppfyller villkoret redan har filtrerats bort kan två rader ligga intill varandra i resultatet utan att vara på varandra följande i kalendern.

Lärdom: tillämpa det glidande fönstret på hela den dagliga serien (filtrera inte i förväg), eller använd datumankarmetoden som automatiskt tar hänsyn till luckor i kalendern. Nämn denna avvägning under intervjun.

Generalisera till valfritt N

Metod 1 (filtrera och bilda öar) generaliseras enkelt: ändra bara HAVING COUNT(*) >= N. Det är den stora fördelen jämfört med summan av flera fönster, som behöver fler ramar när N växer.

För ett parametriserat eller stort N bör ni föredra ömetoden — den kräver en ändring av tröskelvärdet i stället för N−1 manuellt skrivna fönster.

-- only the threshold changes for N = 5
HAVING COUNT(*) >= 5

Välj metod

En snabb beslutsguide att säga högt:

  • Filtrera och bilda öar: tar hänsyn till luckor i kalendern, kan generaliseras till valfritt N och returnerar hela följder — det säkra standardvalet.
  • Glidande fönstersumma: elegant för ett fast, litet N i en tät daglig serie, men se upp med fallgropen mellan ROWS och kalenderdagar.

Att nämna båda metoderna och sedan motivera ert val är precis vad intervjuare på mellan- till seniornivå uppskattar.

Komplett lösning

Det portabla svaret för valfritt N, som tar hänsyn till sammanhängande kalenderdagar och returnerar datumen som uppfyller villkoret:

WITH qualifying AS (
  SELECT sale_date FROM sales WHERE amount > 100
),
numbered AS (
  SELECT sale_date,
    ROW_NUMBER() OVER (ORDER BY sale_date) AS rn
  FROM qualifying
),
islands AS (
  SELECT sale_date - rn AS grp, COUNT(*) AS len
  FROM numbered
  GROUP BY sale_date - rn
  HAVING COUNT(*) >= 3
)
SELECT n.sale_date
FROM numbered n
JOIN islands i ON n.sale_date - n.rn = i.grp
ORDER BY n.sale_date;

Snabb kontroll

Hitta den subtila buggen.

Sammanfattning

För N på varandra följande rader som uppfyller ett villkor:

  • Filtrera och bilda öar: behåll rader som uppfyller villkoret, förankra med date - ROW_NUMBER(), gruppera och använd HAVING COUNT(*) >= N. Metoden kan generaliseras och tar hänsyn till luckor i kalendern.
  • Glidande fönstersumma: flagga rader och summera över fönster med fast N antal rader; elegant, men se upp med skillnaden mellan ROWS och kalenderdagar i förfiltrerade data.

Nästa steg: beräkna en användares aktuella aktiva svit i dag.

Gratis att börja

Lär dig SQL 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
30
Lektioner
120

Vanliga frågor

Är lektionen ”N på varandra följande rader som uppfyller ett villkor” gratis?

Ja – hela texten till ”N på varandra följande rader som uppfyller ett villkor” 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örberedelser inför SQL-intervjun, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelser inför SQL-intervjun innehåller totalt 4 lektioner.

Vad lär jag mig i ”N på varandra följande rader som uppfyller ett villkor”?

Det klassiska fönstermönstret ”tre dagar i rad med försäljning över X”. Ni övar på Förberedelser inför SQL-intervjun 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örberedelser inför SQL-intervjun?

Du behöver inga förkunskaper. Utbildningen i Förberedelser inför SQL-intervjun 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 3 av 4.

Hur lång tid tar lektionen ”N på varandra följande rader som uppfyller ett villkor”?

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örberedelser inför SQL-intervjun-lektionen?

Ja. Varje Förberedelser inför SQL-intervjun-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

  1. Identifiera sammanhängande kalenderdagar
  2. Längsta svit per användare
  3. N på varandra följande rader som uppfyller ett villkor
  4. Aktuell aktiv svit per idag
← Tillbaka till Förberedelser inför SQL-intervjun