Sekretess& Cookies
den här webbplatsen använder cookies. Genom att fortsätta godkänner du deras användning. Läs mer, inklusive hur du kontrollerar cookies.
det finns tillfällen när jag granskar SQL-frågor och hittar personer som använder vänster yttre kopplingar men sedan använda där klausuler som gör dem sammanfogas till inre kopplingar. Nyligen som jag nämnde detta till någon de påminde mig om att jag borde blogga om it…so här bloggar jag om det.
först av, om du inte är bekant med de olika anslutningarna gå vidare och läsa denna andra SQL tips jag skrev., Nu får vi lära oss lite mer om vänster yttre koppling (jag hänvisar till det helt enkelt som vänster koppling härifrån vidare ut).
låt oss börja med några exempeldata. Följande kan användas i början av dina egna frågor om du ska köra dessa tester för dig själv. Som du kan se skapar det två tabeller (tabellvariabler).,
om vi vill returnera alla poster i ”Table1” oavsett om det finns en associerad post i ”Table2” och visa data från ”Table2” när det finns en associerad post skulle vi skriva en vänster JOIN, så:
SELECT * FROM @Table1 tb1 LEFT OUTER JOIN @Table2 tb2 ON tb1.colID = tb2.columnID;
Output:
om vi nu vill lägga till en WHERE-klausul i frågan för att bara få data från ”Table2” där ID är mindre än 4 vi kan göra något så här:
SELECT * FROM @Table1 tb1 LEFT OUTER JOIN @Table2 tb2 ON tb1.colID = tb2.columnID WHERE tb2.columnID < 4;
utgång:
men…såg du att vi bara får värdena där det finns ett matchande ID i båda tabellerna?, Hmmm … det verkar vara väldigt mycket som en inre koppling rätt? Det är för att det är det. Tror du mig inte? Ta en titt på exekveringsplanen efter att ha kört vänster JOIN med och utan var villkoret. Så här ser du:
Så hur kan vi komma runt det här? Tja, eftersom du gör en vänster koppling till att börja med behöver du uppenbarligen eller vill returnera alla poster från” Table1 ”oavsett data i”Table2”., Och om du verkligen inte vill returnera data för vissa poster i ”Table2” kan du filtrera dessa poster i ditt JOIN predicate (”sökkriterierna” i den på delen av JOIN). Till exempel skulle den sista frågan skrivas så här istället:
SELECT * FROM @Table1 tb1 LEFT OUTER JOIN @Table2 tb2 ON tb1.colID = tb2.columnID AND tb2.columnID < 4;
Output:
se hur vi fortfarande får de 5 posterna från” Table1 ”men inte data från” Table2 ” som inte uppfyllde våra kriterier? Det returnerar bara NULLs för data i den tabellen som inte uppfyller kriterierna. Ganska häftigt eller hur?,
och…vi kan titta på exekveringsplanen igen för att bevisa att vi faktiskt använder en vänster JOIN:
vad sägs om när istället för ett värde använder någon IS NULL-villkoret istället? I så fall kan du använda det i WHERE-klausulen.
SELECT * FROM @Table1 tb1 LEFT OUTER JOIN @Table2 tb2 ON tb1.colID = tb2.columnID WHERE tb2.columnID IS NULL;
Output:
och låt oss titta på exekveringsplanen igen:
Lägg märke till att den utför vänster koppling och filtrerar sedan data för NULL-posterna? Det är vad vi vill att det ska göra och uppriktigt sagt, det är vad vi förmodligen förväntade oss att det ska göra.
vad händer om vi använder är inte NULL istället? Det är en annan historia., Jag ska förstöra överraskningen och bara berätta att det kommer att göra en inre koppling precis som det skulle med ett verkligt värde. Om du inte tror mig gå vidare och köra frågan själv och titta på avrättningsplanen.
Så, där har du det; det är hur en vänster koppling kan eller kanske inte faktiskt vara en vänster koppling. Förhoppningsvis hjälper denna information dig att skriva bättre, eller åtminstone mer informerade frågor.