Forberedelse til SQL-intervju · leksjon

N sammenhengende rader som oppfyller en betingelse

Det klassiske vindusmønsteret «tre sammenhengende dager med salg over X».

Leksjon 3 av 413 trinn

N sammenhengende rader som oppfyller en betingelse er en gratis leksjon i Forberedelse til SQL-intervju på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Forberedelse til SQL-intervju, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Forberedelse til SQL-intervju inneholder totalt 4 leksjoner.

En LeetCode-klassiker

Dette er en av de vanligste SQL-oppgavene i intervjuer: «Finn alle datoer med minst tre sammenhengende dager der salget oversteg en terskel», eller LeetCode-favoritten «rapporter stadionet med 3+ sammenhengende rader med oppmøte over 100».

Strukturen er alltid den samme: En rad oppfyller kravet bare hvis den inngår i en rekke med N sammenhengende rader som oppfyller kravet. Denne leksjonen viser to ryddige løsninger og fallgruven som tar de fleste kandidater.

Eksempeldataene

Vi bruker en daglig sales-tabell. Betingelsen er amount > 100. Vi må returnere hver dag som inngår i en rekke på minst 3 sammenhengende kalenderdager der alle oppfyller betingelsen.

  • sale_date — én rad per dag
  • amount — totalt salg den dagen

Viktig detalj: Radene må være sammenhengende i rekkefølgen, og i datobaserte varianter også sammenhengende i kalenderen.

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

Tilnærming 1: Filtrer først, bygg øyer

Den robuste tilnærmingen er først å beholde bare rader som oppfyller kravet, deretter gruppere radene som står igjen i sammenhengende øyer, og til slutt beholde øyer med lengde minst N.

Første trinn er WHERE-filteret. I andre trinn bruker vi ankeret fra gaps-and-islands på nytt. Fordi vi filtrerte først, betyr en øy her «en rekke med sammenhengende dager som oppfyller kravet».

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

Forankring av rekker som oppfyller kravet

Nummerer radene som oppfyller kravet etter dato, og trekk fra for å få øyas forankring. Rader som ligger sammenhengende i kalenderen OG alle oppfyller kravet, deler en forankring; enhver dag som ikke oppfyller kravet, er fjernet, og dermed brytes rekken akkurat der den skal.

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;

Behold øyer som er lange nok

Gruppér etter forankringen, tell radene, og behold bare grupper med COUNT(*) >= 3. Hvis intervjueren vil ha de enkelte datoene som oppfyller kravet tilbake, kobler De de beholdte forankringene til de nummererte radene.

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;

Tilnærming 2: Glidende COUNT-vindu

En smidigere tilnærming når N er liten og fast, er å bruke en vindusramme til å telle hvor mange av radene rundt som også oppfyller kravet. Hvis et vindu med N sammenhengende rader som inneholder denne raden, bare består av rader som oppfyller kravet, er raden med i svaret.

Legg først til et boolsk flagg, og summer deretter flagget over glidende rammer.

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

Summering over tre rammer

For en rekke på nøyaktig 3 er en rad med i svaret hvis vinduet med 3 rader som slutter her, er sentrert her eller starter her, summerer til 3. Beregn de tre rullerende summene, og test om noen av dem er lik 3.

Dette er teknikken bak 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);

Fallgruven med hull i kalenderen

Tilnærmingen med vindussum bruker ROWS, som teller tilstøtende resultatrader, ikke tilstøtende kalenderdager. Hvis en dag som ikke oppfyller kravet, allerede er filtrert bort, kan to rader stå ved siden av hverandre i resultatet uten å være sammenhengende i kalenderen.

Lærdom: Bruk det glidende vinduet på hele den daglige serien (ikke forhåndsfiltrer), eller bruk metoden med datoforankring, som automatisk tar hensyn til hull i kalenderen. Nevn dette avveiningen i intervjuet.

Generalisering til vilkårlig N

Tilnærming 1 (filtrer-først-bygg-øy) generaliserer uten problemer: Endre bare HAVING COUNT(*) >= N. Det er den store fordelen sammenlignet med summering over flere vinduer, som trenger flere rammer når N øker.

For en parameterisert eller stor N bør De foretrekke øymetoden — den krever én endring av terskelen i stedet for N−1 håndskrevne vinduer.

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

Velg en tilnærming

En kort beslutningsregel De kan si høyt:

  • Filtrer-først-bygg-øy: tar hensyn til hull i kalenderen, generaliserer til enhver N og returnerer komplette rekker — det trygge standardvalget.
  • Glidende vindussum: elegant for en fast, liten N i en tett daglig serie, men vær oppmerksom på fellen med ROWS kontra kalender.

Det er nettopp dette intervjuere på mellom- og seniornivå belønner: at De nevner begge, og deretter begrunner valget.

Komplett løsning

Den portable løsningen for vilkårlig N som tar hensyn til sammenheng i kalenderen og returnerer datoene som oppfyller kravet:

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;

Rask kontroll

Finn den subtile feilen.

Oppsummering

For N sammenhengende rader som oppfyller en betingelse:

  • Filtrer-først-bygg-øy: behold radene som oppfyller kravet, forankre med date - ROW_NUMBER(), gruppér, og bruk HAVING COUNT(*) >= N. Generaliserer og tar hensyn til hull i kalenderen.
  • Glidende vindussum: marker rader og summer over faste vinduer på N rader; elegant, men vær oppmerksom på ROWS kontra kalender når dataene er forhåndsfiltrert.

Neste trinn: beregne en brukers nåværende aktive serie per i dag.

Gratis å komme i gang

Lær deg SQL med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
30
Leksjoner
120

Ofte stilte spørsmål

Er leksjonen «N sammenhengende rader som oppfyller en betingelse» gratis?

Ja – hele teksten i «N sammenhengende rader som oppfyller en betingelse» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Forberedelse til SQL-intervju-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Forberedelse til SQL-intervju inneholder totalt 4 leksjoner.

Hva lærer jeg i «N sammenhengende rader som oppfyller en betingelse»?

Det klassiske vindusmønsteret «tre sammenhengende dager med salg over X». Du øver på Forberedelse til SQL-intervju med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Forberedelse til SQL-intervju?

Ingen tidligere erfaring er nødvendig. Forberedelse til SQL-intervju på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «N sammenhengende rader som oppfyller en betingelse»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Forberedelse til SQL-intervju-leksjonen?

Ja. Alle Forberedelse til SQL-intervju-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Oppdage sammenhengende kalenderdager
  2. Lengste rekke per bruker
  3. N sammenhengende rader som oppfyller en betingelse
  4. Gjeldende aktive rekke per i dag
← Tilbake til Forberedelse til SQL-intervju