Förberedelse inför kodningsintervjuer · Lektion

Fällan med WHERE på en outer join

Varför filtrering av en outer-joinad kolumn i WHERE tyst gör den till en inner join

Lektion 4 av 413 steg

Fällan med WHERE på en outer join är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 4 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.

Fallgropen som fångar alla

Det här är det vanligaste felet med outer join som intervjuare brukar plantera: ”Visa alla kunder och deras order från 2024, inklusive kunder utan order från 2024.”

En kandidat skriver en LEFT JOIN och lägger sedan till ett datumfilter i WHERE. Då försvinner kunderna utan order från 2024 utan att det märks. LEFT JOIN förvandlas obemärkt till en INNER JOIN. Att förstå varför är ett tecken på erfarenhet på seniornivå.

Den felaktiga frågan

Här är misstaget. Det ser rimligt ut: behåll alla kunder, koppla ihop deras order och filtrera till 2024.

Men kunder utan order, eller utan order från 2024, försvinner från resultatet. Kravet att ta med dem uppfylls inte.

-- BUG: drops customers with no 2024 order
SELECT c.name, o.id, o.order_date
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.order_date >= '2024-01-01';

Därför fungerar det inte

Påminn Er om operationernas ordningsföljd: JOIN körs först och skapar rader där omatchade kunder har NULL i varje orderkolumn. Sedan körs WHERE.

För en omatchad kund är o.order_date NULL, så o.order_date >= '2024-01-01' utvärderas till UNKNOWN, inte till sant. WHERE behåller bara rader som är sanna, så NULL-raderna filtreras bort – exakt de rader som LEFT JOIN arbetade för att bevara.

NULL besegrar filtret

Alla jämförelser med NULL ger UNKNOWN: NULL >= '2024-01-01' är UNKNOWN, NULL = 5 är UNKNOWN och även NULL <> 5 är UNKNOWN.

Eftersom WHERE endast släpper igenom rader som utvärderas till TRUE tas varje bevarad rad utan matchning bort. Hela poängen med outer join förstörs av ett enda WHERE-predikat på en kolumn från högertabellen.

Lösningen: filtrera i ON

Flytta filtret till ON-satsen. Där blir det en del av matchningsvillkoret och tillämpas innan rader bevaras, så omatchade kunder finns fortfarande kvar med NULL-värden.

-- CORRECT: filter lives in ON
SELECT c.name, o.id, o.order_date
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.id
  AND o.order_date >= '2024-01-01';
-- customers with no 2024 order: kept, NULL order

ON jämfört med WHERE i en mening

Regeln Ni ska kunna säga i en intervju:

För den bevarade (yttre) tabellen hör villkor som gäller den andra tabellen hemma i ON; villkor som gäller den bevarade tabellen själv hör hemma i WHERE.

  • ON avgör vad som räknas som en matchning (körs under joinen).
  • WHERE filtrerar de slutliga raderna (körs efteråt och tar bort NULL-rader).

Resultat sida vid sida

Samma data, två placeringar och olika svar. Anta att Carol inte har någon order från 2024.

  • Filter i WHERE: Carol försvinner. Resultatet motsvarar i praktiken en inner join.
  • Filter i ON: Carol visas en gång med NULL i orderkolumnerna, så kravet uppfylls.

Skillnaden i resultat är själva poängen med fallgropen.

-- ON version output
-- Alice | 50 | 2024-03-01
-- Bob   | 20 | 2024-05-02
-- Carol | NULL | NULL   <-- preserved

När WHERE faktiskt är rätt

Alla WHERE-villkor i en outer join är inte fel. Det är helt korrekt att filtrera den bevarade tabellen – det involverar inte NULL-värden från joinen.

Anti-joinen från föregående lektion använder dessutom avsiktligt WHERE o.id IS NULL för att utnyttja just detta beteende. Färdigheten ligger i att veta vilket fall Ni har framför Er.

-- Fine: filtering the preserved (left) table
SELECT c.name, o.id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE c.country = 'US';

En tumregel för att upptäcka felet

När Ni granskar en outer join ska Ni leta efter predikat på den icke-bevarade tabellen i WHERE-satsen (förutom IS NULL-tester för anti-join).

Om Ni ser o.someColumn = ... eller ett intervall- eller likhetsvillkor på den yttre sidan i WHERE, bör Ni misstänka fallgropen. Fråga Er: ”Förvandlar detta min LEFT JOIN till en INNER JOIN?” Oftast gör det det.

Flera villkor

Ni kan kombinera båda placeringarna. Matchningsvillkor på högertabellen hör hemma i ON, medan ett genuint filter efter joinen på vänstertabellen hör hemma i WHERE. De fungerar bra tillsammans.

SELECT c.name, o.id, o.amount
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.id
  AND o.amount > 100          -- match condition
WHERE c.signup_year = 2023;    -- preserved-table filter

Så förklarar Ni det högt

I intervjun ska Ni beskriva mekanismen, inte bara lösningen:

”Joinen körs först och fyller kolumnerna från höger tabell med NULL för omatchade rader. Ett WHERE-predikat på dessa kolumner utvärderas till UNKNOWN för NULL-raderna, och WHERE tar bort rader som inte är sanna, så outer join förvandlas till en inner join. Genom att placera predikatet i ON förblir det ett matchningsvillkor och de omatchade raderna bevaras.” Den förklaringen fungerar varje gång.

Snabb kontroll

Ni måste lista alla kunder och endast deras order från 2024, även kunder som inte hade några.

Sammanfattning

Att filtrera en kolumn från den icke-bevarade tabellen i WHERE förvandlar obemärkt en outer join till en inner join, eftersom NULL-värden från omatchade rader inte uppfyller predikatet (UNKNOWN) och WHERE tar bort dem.

  • Matchningsvillkor för den icke-bevarade tabellen hör hemma i ON.
  • Filter på den bevarade tabellen hör hemma i WHERE.
  • IS NULL i WHERE är den avsiktliga anti-joinen, inte fallgropen.
  • Förklara operationernas ordningsföljd för att visa att Ni förstår den.
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 ”Fällan med WHERE på en outer join” gratis?

Ja – hela texten till ”Fällan med WHERE på en outer join” 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 ”Fällan med WHERE på en outer join”?

Varför filtrering av en outer-joinad kolumn i WHERE tyst gör den till en inner join 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 4 av 4.

Hur lång tid tar lektionen ”Fällan med WHERE på en outer join”?

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. LEFT JOIN och bevarande av omatchade rader
  2. Semantik för RIGHT och FULL OUTER JOIN
  3. Hitta rader utan matchning (anti-join)
  4. Fällan med WHERE på en outer join
← Tillbaka till Förberedelse inför kodningsintervjuer