När du jämför publicerade kampanjer med en lista över alla planerade kampanjer kan en vanlig join tappa rader som saknar matchning. Med en RIGHT JOIN finns varje rad från den högra tabellen kvar, men resultatet kan ändå bli färre än väntat om ett filter hamnar fel.

RIGHT JOIN bevarar raderna på höger sida
- Höger tabell: alla dess rader kommer med, även utan matchning.
- Omatchade rader: kolumner från den vänstra tabellen får värdet
NULL. - WHERE-filter: ett villkor på den vänstra tabellen kan ta bort rader som joinen annars bevarar.
- LEFT JOIN: du kan ofta skriva om frågan genom att byta tabellordning.
- SQLite: kontrollera versionen om frågan körs i en äldre miljö.
Höger sida betyder tabellen efter RIGHT JOIN
Tänk dig att en webbplats har en tabell med kampanjer och en annan med publicerade inlägg. Om listan över planerade kampanjer ska visas även när inget inlägg har publicerats, placeras kampanjtabellen till höger i joinen. Det är tabellens position i frågan, inte dess namn eller roll i datamodellen, som avgör vilken sida som bevaras.
En RIGHT JOIN kombinerar matchande rader och behåller dessutom varje rad från den högra tabellen. Saknas en motsvarighet till vänster fylls den vänstra tabellens kolumner med NULL. Jag tycker att den regeln blir lättast att läsa när du först bestämmer vilken tabell som absolut inte får tappas bort.
Ett kampanjexempel visar vilka rader som blir kvar
Anta att posts bara innehåller publicerade inlägg och campaigns innehåller hela planeringen. Då gör frågan nedan kampanjlistan till den bevarade sidan:
SELECT
p.title,
c.campaign_name
FROM posts AS p
RIGHT JOIN campaigns AS c
ON p.campaign_id = c.id;
Om kampanjen ”Vårguide” saknar ett publicerat inlägg visas den ändå, med NULL i title. Om flera inlägg pekar på samma kampanj blir kampanjen däremot synlig på flera resultatrader, en för varje matchning. Joinen garanterar rader från höger tabell, inte en rad per nyckel.
Ett WHERE-villkor kan råka radera de omatchade raderna
Här uppstår ett vanligt felsökningsproblem: joinen bevarar kampanjen, men filtret efteråt kräver ett värde som bara finns i den vänstra tabellen. Då sorterar WHERE bort rader med NULL, och den yttre joinen beter sig i praktiken mer som en inner join för just det villkoret.
| Situation | Trolig effekt | Gör så här |
|---|---|---|
| En kampanj saknar publicerat inlägg | p.title blir NULL, men kampanjen finns kvar. |
Behåll filtret på den högra tabellen, eller placera matchningsvillkoret i ON när det passar frågan. |
WHERE p.status = 'published' |
Rader utan matchande inlägg tas bort eftersom NULL inte uppfyller villkoret. |
Kontrollera om omatchade kampanjer ska finnas kvar innan du filtrerar på p. |
| Du vill hitta kampanjer utan inlägg | Matchade kampanjer filtreras bort medan omatchade återstår. | Testa en vänsterkolumn som är obligatorisk vid träff, till exempel p.id IS NULL. |
Skillnaden mellan ON och WHERE är alltså inte kosmetisk. Ett villkor i ON avgör vilka rader som matchar; ett villkor i WHERE filtrerar resultatet efter joinen.
LEFT JOIN ger ofta samma resultat med tydligare läsriktning
Om du hellre vill börja med tabellen som ska bevaras kan du byta plats på tabellerna och använda LEFT JOIN. Samma kampanjfråga kan skrivas så här:
SELECT
p.title,
c.campaign_name
FROM campaigns AS c
LEFT JOIN posts AS p
ON p.campaign_id = c.id;
Kolumnerna ligger fortfarande i samma ordning i resultatet, eftersom SELECT styr den. I MySQL omvandlas RIGHT OUTER JOIN till en motsvarande LEFT JOIN med tabellerna omkastade, enligt MySQL Reference Manual. Jag skulle välja LEFT JOIN när den bevarade tabellen kan stå först; det gör riktningen lättare att följa när frågan växer.
SQLite kräver en tillräckligt ny version
Om samma SQL fungerar på en server men inte i ett lokalt testverktyg behöver felet inte ligga i frågan. SQLite lade till stöd för RIGHT och FULL OUTER JOIN i version 3.39.0, enligt SQLite 3.39.0 release notes. Äldre SQLite-versioner kan därför avvisa syntaxen.
Kontrollera vilken SQLite-version verktyget faktiskt använder. Om du behöver stödja äldre versioner kan du ofta skriva om frågan som en LEFT JOIN och byta tabellordning; kontrollera samtidigt att filter och kolumnordning behåller samma innebörd.
Välj join efter den rad som aldrig får försvinna
Vid kampanjrapporten är beslutet enkelt: om varje planerad kampanj måste synas, gör kampanjtabellen till den bevarade sidan. Skriv RIGHT JOIN när det hjälper läsbarheten i din befintliga fråga, men föredra ofta LEFT JOIN med den viktiga tabellen först när du formar en ny.
Om en kampanj ändå saknas, börja med att kontrollera tabellernas ordning, matchningsvillkoret och filtren i WHERE. En enda rad kan försvinna där, trots att join-typen först såg rätt ut.