Förberedelse inför kodningsintervjuer · Lektion

Längsta svit per användare

Beräkna den maximala längden på en sammanhängande följd inom varje grupp.

Lektion 2 av 413 steg

Längsta svit per användare är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 2 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

En vanlig följdfråga efter identifiering av på varandra följande dagar är: "Vilken är den längsta sviten av aktiva dagar i följd för varje användare?" Produkt- och tillväxtteam ställer ständigt den här frågan för att mäta engagemang.

Du vet redan hur du identifierar varje svit. Det nya steget är att hitta den maximala svitlängden per användare och ofta även returnera datumen för den bästa sviten. Den här lektionen bygger direkt vidare på grundstrukturen för luckor och öar.

Påminnelse: öbyggaren

I föregående lektion använder grupperingen per svit login_date - ROW_NUMBER() som ankare för ön. Varje användare kan ha flera öar; först beräknar vi en rad per ö och reducerar sedan till en rad per användare.

Ha denna plan i två lager i åtanke: bygg först öarna och aggregera sedan öarna.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
)
SELECT user_id, login_date - rn AS grp
FROM numbered;

En rad per ö

Sammanfatta varje ö till en enda sammanfattningsrad med dess längd och datumintervall. Gruppera efter användare och ankaret och beräkna måtten.

Vi kallar denna CTE islands så att nästa lager kan läsa från den på ett tydligt sätt.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
),
islands AS (
  SELECT user_id,
    MIN(login_date) AS streak_start,
    MAX(login_date) AS streak_end,
    COUNT(*)        AS streak_len
  FROM numbered
  GROUP BY user_id, login_date - rn
)
SELECT * FROM islands;

Enkelt svar: MAX-längd

Om intervjuaren bara vill ha längden är det sista steget en enda rad: gruppera öarna per användare och hämta den maximala längden.

Detta är det renaste svaret när start- och slutdatum inte behövs.

-- ...numbered and islands CTEs as before...
SELECT
  user_id,
  MAX(streak_len) AS longest_streak
FROM islands
GROUP BY user_id
ORDER BY user_id;

Returnera även datumen

Ofta lägger intervjuaren till: "och visa när den sviten inträffade." En vanlig MAX kan inte tala om vilken ö som vann. Du måste rangordna öarna inom varje användare och behålla rang 1.

Använd ROW_NUMBER sorterat efter längden i fallande ordning så att varje användares bästa svit får rang 1. Lägg till en tie-breaker så att lika resultat avgörs deterministiskt.

ROW_NUMBER() OVER (
  PARTITION BY user_id
  ORDER BY streak_len DESC, streak_start ASC
) AS rnk

Rangordna och filtrera

Omslut rangordningen i en CTE och filtrera sedan till rnk = 1. Du kan inte filtrera på en fönsterfunktion direkt i WHERE, så det extra lagret är obligatoriskt.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
),
islands AS (
  SELECT user_id,
    MIN(login_date) AS streak_start,
    MAX(login_date) AS streak_end,
    COUNT(*)        AS streak_len
  FROM numbered
  GROUP BY user_id, login_date - rn
),
ranked AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY user_id
      ORDER BY streak_len DESC, streak_start
    ) AS rnk
  FROM islands
)
SELECT user_id, streak_start, streak_end, streak_len
FROM ranked
WHERE rnk = 1;

RANK eller ROW_NUMBER vid lika resultat

Vad händer om en användare har två sviter med samma maximala längd och intervjuaren vill att båda ska returneras? Byt ut ROW_NUMBER mot RANK och behåll rnk = 1.

  • ROW_NUMBER — exakt en vinnare per användare (godtyckligt vid lika resultat om du inte lägger till en tie-breaker).
  • RANK — alla lika långa längsta sviter får rang 1 och behålls.

Förtydliga vilket beteende de vill ha; det visar att du uppmärksammar specialfall.

RANK() OVER (
  PARTITION BY user_id
  ORDER BY streak_len DESC
) AS rnk  -- keep all rnk = 1

Exempel med genomgång

Anta att användare 7 loggade in 1–4 januari, sedan 10–11 januari och därefter 20–23 januari. Tre öar med längderna 4, 2 och 4. Den längsta längden är 4, och det finns en lika lång svit.

  • Med ROW_NUMBER + tie-breaker streak_start: returneras endast sviten 1–4 januari.
  • Med RANK: returneras både sviten 1–4 januari och sviten 20–23 januari.

Att säga detta högt visar att du har tänkt igenom specialfall med lika resultat.

Hantera användare utan inloggningar

En intervjuare kan fråga: "Hur är det med användare som aldrig loggat in?" Dessa användare har inga rader i logins och försvinner därför från resultatet. Om de måste visas med en svit på 0 använder ni LEFT JOIN mot hela tabellen users och COALESCE.

SELECT u.user_id,
  COALESCE(MAX(i.streak_len), 0) AS longest_streak
FROM users u
LEFT JOIN islands i ON i.user_id = u.user_id
GROUP BY u.user_id;

Prestanda

Det här mönstret gör en enda ordnad genomläsning av data samt en gruppering. Så här håller ni det snabbt:

  • Säkerställ ett index på (user_id, login_date) så att fönstrets ORDER BY undviker en sortering.
  • Ta bort dubbletter tidigt om källan innehåller flera händelser per dag.
  • Undvik att omsluta login_date i funktioner i ORDER BY, eftersom det kan hindra användningen av index.

För mycket stora tabeller presterar detta klart bättre än alla varianter som använder self-join.

Komplett intervjusvar

Här är den kompletta, genomarbetade frågan som returnerar varje användares längsta svit med dess datum — den version ni skriver på whiteboarden.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
),
islands AS (
  SELECT user_id,
    MIN(login_date) AS streak_start,
    MAX(login_date) AS streak_end,
    COUNT(*)        AS streak_len
  FROM numbered
  GROUP BY user_id, login_date - rn
),
ranked AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY user_id
      ORDER BY streak_len DESC, streak_start
    ) AS rnk
  FROM islands
)
SELECT user_id, streak_start, streak_end, streak_len
FROM ranked
WHERE rnk = 1
ORDER BY user_id;

Snabb kontroll

Välj rätt verktyg för kravet.

Sammanfattning

Så här beräknar ni den längsta sviten per användare:

  • Skapa öar med ankaret login_date - ROW_NUMBER().
  • Reducera varje ö till längd samt datumintervall.
  • Om ni bara behöver längden använder ni MAX(streak_len), grupperat per användare.
  • Om ni även behöver datumen rangordnar ni öarna per användare och behåller rang 1 — använd RANK för att ta med lika resultat och ROW_NUMBER för att välja en enda vinnare.
  • Använd LEFT JOIN mot users för att även visa användare med en svit på 0.

Nästa steg: hitta N på varandra följande rader som uppfyller ett villkor.

Gratis att börja

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 ”Längsta svit per användare” gratis?

Ja – hela texten till ”Längsta svit per användare” 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 ”Längsta svit per användare”?

Beräkna den maximala längden på en sammanhängande följd inom varje grupp. 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 2 av 4.

Hur lång tid tar lektionen ”Längsta svit per användare”?

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

  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örberedelse inför kodningsintervjuer