sql >> Database >  >> RDS >> Database

Uw ultieme gids voor SQL-joins:OUTER JOIN - Deel 2

Outer join staat vandaag centraal. En dit is deel 2 van je ultieme gids voor SQL-joins. Als je deel 1 hebt gemist, is hier de link.

Zo te zien is uiterlijk het tegenovergestelde van innerlijk. Als je de outer join echter op deze manier beschouwt, raak je in de war. Als klap op de vuurpijl hoef je het woord outer niet op te nemen expliciet in uw syntaxis. Het is optioneel!

Maar laten we, voordat we erin duiken, nulls bespreken met betrekking tot outer joins.

Nulls en OUTER JOIN

Wanneer u 2 tabellen samenvoegt, kan een van de waarden van beide tabellen null zijn. Voor INNER JOIN's komen records met nulls niet overeen en worden ze verwijderd en verschijnen ze niet in de resultatenset. Als u de records wilt krijgen die niet overeenkomen, is uw enige optie OUTER JOIN.

Terugkerend naar antoniemen, is dat niet het tegenovergestelde van INNER JOINs? Niet helemaal, zoals je in het volgende gedeelte zult zien.

Alles over SQL Server OUTER JOIN

Het begrijpen van outer joins begint met de output. Hier is een volledige lijst van wat u kunt verwachten:

  • Alle records die overeenkomen met de join-voorwaarde of het predikaat. Dat is de uitdrukking direct na het ON-sleutelwoord, net zoals de INNER JOIN-uitvoer. We noemen dit probleem de binnenste rij .
  • Niet-NULL-waarden van links tabel met de nul-tegenhangers van rechts tafel. We noemen dit probleem buitenste rijen .
  • Niet-NULL-waarden van rechts tabel met de nul-tegenhangers van links tafel. Dit is een andere vorm van buitenste rijen.
  • Ten slotte kan het een combinatie zijn van alle hierboven beschreven dingen.

Met die lijst kunnen we zeggen dat OUTER JOIN de binnenste en buitenste rijen retourneert .

  • Inner – omdat de exacte resultaten van de INNER JOIN kan zijn terug.
  • Buitenste – omdat de buitenste rijen ook . kunnen zijn terug.

Het is het verschil met INNER JOIN.

INNER WORDT ALLEEN RETOUR BINNENRIJEN. OUTER JOINS KUNNEN ZOWEL DE BINNEN- EN BUITENRIJ RETOURNEREN

Merk op dat ik "kan zijn" en "kan ook zijn" gebruikte. Het hangt af van uw WHERE-clausule (of als u ooit een WHERE-clausule opneemt) of deze zowel de binnenste als de buitenste rijen retourneert.

Maar hoe kun je uit een SELECT-instructie bepalen wat de linker- of rechtertabel is ? Goede vraag!

Hoe weet je wat de linker- of rechtertabel is in een join?

We kunnen deze vraag beantwoorden met voorbeelden:

SELECT *
FROM Table1 a
LEFT OUTER JOIN Table2 b on a.column1 = b.column1

Uit het bovenstaande voorbeeld, Tabel1 is de linkertafel, en Tabel2 is de juiste tafel. Laten we nu nog een voorbeeld nemen. Deze keer is het een simpele multi-join.

SELECT *
FROM Table1 a
LEFT OUTER JOIN Table2 b on a.column1 = b.column1
LEFT OUTER JOIN Table3 c on b.column2 = c.column1

In dit geval, om te weten wat links of rechts is, onthoud dat een join op 2 tafels werkt.

Tabel1 is nog steeds de linkertafel, en Tabel2 is de juiste tafel. Dit verwijst naar het samenvoegen van 2 tabellen:Tabel1 en Tabel2 . Hoe zit het met deelname aan Table2 en Tabel3 ? Tabel2 wordt de linkertafel, en Tabel3 is de juiste tafel.

Als we een vierde tabel toevoegen, Tabel3 wordt de linkertafel, en Tabel4 is de juiste tafel. Maar daar houdt het niet op. We kunnen een andere tafel toevoegen aan de Tabel1 . Hier is een voorbeeld:

SELECT *
FROM Table1 a
LEFT OUTER JOIN Table2 b on a.column1 = b.column1
LEFT OUTER JOIN Table3 c on b.column2 = c.column1
LEFT OUTER JOIN Table4 d on c.column1 = d.column2
LEFT OUTER JOIN Table5 e on a.column2 = e.column1

Tabel1 is de linkertafel, en Tabel5 is de juiste tafel. Je kunt hetzelfde ook doen met de andere tafels.

Oké, laten we teruggaan naar de lijst met verwachte outputs hierboven. Hieruit kunnen we ook de outer joins afleiden.

Soorten Outer Joins

Er zijn 3 typen gebaseerd op de OUTER JOIN-uitgangen.

LEFT OUTER JOIN (LINKER JOIN)

LEFT JOIN retourneert binnenste rijen + niet-NULL-waarden van links tabel met de nul-tegenhangers van de juiste tabel. Daarom is het LEFT JOIN omdat de linkertabel de dominante is van de twee tabellen binnen de join met niet-null-waarden.

LINKER BUITENSTE JOIN VOORBEELD 1
-- Return all customerIDs with orders and no orders

USE AdventureWorks
GO

SELECT
 c.CustomerID
,soh.OrderDate
FROM Sales.Customer c
LEFT OUTER JOIN Sales.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID 

In het bovenstaande voorbeeld, de klant is de linkertabel, en SalesOrderHeader is de juiste tafel. Het resultaat van de zoekopdracht is 32.166 records - het omvat zowel binnen- als buitenrijen. Je kunt een deel ervan zien in figuur 1:

Stel dat we alleen de buitenste rijen willen retourneren of de klanten zonder bestellingen. Voeg hiervoor een WHERE-component toe om alleen rijen met nulls uit SalesOrderHeader op te nemen .

SELECT
 c.CustomerID
,soh.OrderDate
FROM Sales.Customer c
LEFT OUTER JOIN Sales.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID
WHERE soh.SalesOrderID IS NULL

De resultaatset die ik heb gekregen is 701 records . Ze houden allemaal van de null OrderDate uit figuur 1.

Als ik alleen de binnenste rijen krijg, is het resultaat 31.465 records . Ik kan dit doen door de WHERE-clausule te wijzigen om die SalesOrderID's op te nemen die niet nul zijn. Of ik kan de join veranderen in een INNER JOIN en de WHERE-component verwijderen.

Laten we de records samenvatten om te zien of het uit de uitvoer van het eerste voorbeeld komt zonder de WHERE-component.

Binnenste rijen Buitenste rijen Totaal aantal rijen
31.465 records 701 records 32.166 records

Uit het totale aantal rijen hierboven met 32.166 records, kunt u zien dat het uitcheckt met de eerste voorbeeldresultaten. Dit laat ook zien hoe LEFT OUTER JOIN werkt.

LINKER BUITENSTE JOIN VOORBEELD 2

Dit keer is het voorbeeld een multi-join. Merk ook op dat we het OUTER-zoekwoord schrappen.

-- show the people with and without addresses from AdventureWorks
USE AdventureWorks
GO

SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
LEFT JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
LEFT JOIN Person.Address a ON bea.AddressID = a.AddressID
LEFT JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID 

Het genereerde 19.996 records. U kunt het gedeelte van de uitvoer in Afbeelding 2 hieronder bekijken. De records met null AddressLine1 zijn buitenste rijen. Daarboven zijn de binnenste rijen.

RIGHT OUTER JOIN (RIGHT JOIN)

RIGHT JOIN retourneert binnenste rijen + niet-NULL-waarden van rechts tabel met de nul-tegenhangers van de linkertabel.

RECHTS BUITENSTE JOIN VOORBEELD 1
-- From the product reviews, return the products without product reviews
USE AdventureWorks
GO

SELECT
P.Name
FROM Production.ProductReview pr
RIGHT OUTER JOIN Production.Product p ON pr.ProductID = p.ProductID
WHERE pr.ProductReviewID IS NULL 

Afbeelding 3 toont 10 van de 501 records in de resultatenset.

In het bovenstaande voorbeeld, ProductReview is de linkertabel, en het product is de juiste tafel. Aangezien dit een RIGHT OUTER JOIN is, zijn we van plan om de niet-NULL-waarden uit de rechtertabel op te nemen.

De keuze tussen LEFT JOIN of RIGHT JOIN hangt echter van u af. Waarom? Omdat u de zoekopdracht kunt uitdrukken, of het nu LEFT of RIGHT JOIN is, en dezelfde resultaten krijgt. Laten we het proberen met een LEFT JOIN.

-- return the products without product reviews using LEFT OUTER JOIN
USE AdventureWorks
GO

SELECT
P.Name
FROM Production.Product p
LEFT OUTER JOIN Production.ProductReview pr ON pr.ProductID = p.ProductID
WHERE pr.ProductReviewID IS NULL

Probeer het bovenstaande uit te voeren en u krijgt hetzelfde resultaat als in figuur 3. Maar denkt u dat de Query Optimizer ze anders zal behandelen? Laten we eens kijken in het uitvoeringsplan van beide in figuur 4.

Als dit nieuw voor u is, zijn er enkele verrassingen in het uitvoeringsplan.

  1. De diagrammen zien er hetzelfde uit, en ze zijn:probeer een Vergelijk Showplan , en je ziet dezelfde QueryPlanHash .
  2. Let op het bovenste diagram met een Merge-join. We gebruikten een RIGHT OUTER JOIN, maar SQL Server veranderde deze in LEFT OUTER JOIN. Het verwisselde ook de linker- en rechtertafel. Het maakt het gelijk aan de tweede zoekopdracht met de LEFT JOIN.

Zoals je nu ziet, zijn de resultaten hetzelfde. Kies dus welke van de OUTER JOINs handiger is.

Waarom heeft SQL Server de RIGHT JOIN veranderd in LEFT JOIN?

De database-engine hoeft niet de manier te volgen waarop u de logische joins uitdrukt. Zolang het correcte resultaten kan produceren op de snelst mogelijke manier, zal het veranderingen aanbrengen. Zelfs snelkoppelingen.

Trek niet de conclusie dat RGHT JOIN slecht is en LEFT JOIN goed.

RECHTS BUITENSTE JOIN VOORBEELD 2

Bekijk het onderstaande voorbeeld:

-- Get the unassigned addresses and the address types with no addresses
SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
RIGHT JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
RIGHT JOIN Person.Address a ON bea.AddressID = a.AddressID
RIGHT JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID
WHERE P.BusinessEntityID IS NULL 

Er zijn 2 dingen die u uit deze query kunt halen, zoals u kunt zien in Afbeelding 5 hieronder:

De zoekopdrachtresultaten laten het volgende zien:

  1. De niet-toegewezen adressen - deze records zijn die met null-namen.
  2. Adrestypen zonder adressen. De adrestypen Archief, Facturering en Primair hebben geen corresponderende adressen. Die zijn van records 817 tot 819.

VOLLEDIGE OUTER JOIN (VOLLEDIGE JOIN)

FULL JOIN retourneert een combinatie van binnenste rijen en buitenste rijen, links en rechts.

-- Get people with and without addresses, unassigned addresses, and address types without addresses
SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
FULL JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
FULL JOIN Person.Address a ON bea.AddressID = a.AddressID
FULL JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID

De resultatenset bevat 20.815 records. Zoals je zou verwachten, is het een totaal aantal records uit de resultatenset van INNER JOIN, LEFT JOIN en RIGHT JOIN.

LEFT en RIGHT JOIN bevatten een WHERE-clausule om alleen de resultaten met nulls in linker- of rechtertabellen weer te geven.

INNER JOIN LINKER DEELNAME
(WAAR a.AddressID NULL IS)
RECHTS DEELNEMING
(WAAR P.BusinessEntityID NULL IS)
TOTAAL (zelfde als FULL JOIN)
18.798 records 1.198 records 819 records 20.815 records

Merk op dat de FULL JOIN een enorme resultatenset kan produceren uit grote tabellen. Gebruik het dus alleen wanneer u het alleen nodig heeft.

Praktisch gebruik van OUTER JOIN

Als je nog steeds twijfelt wanneer je OUTER JOIN kunt en moet gebruiken, volgen hier enkele ideeën.

Buitenste joins die zowel binnenste als buitenste rijen uitvoeren

Voorbeelden kunnen zijn:

  • Alfabetische lijst van betaalde en onbetaalde bestellingen van klanten.
  • Alfabetische lijst van werknemers die te laat of niet te laat zijn gekomen.
  • Een lijst van polishouders die hun meest recente verzekeringspolissen hebben vernieuwd en niet hebben verlengd.

Outer joins die alleen buitenste rijen uitvoeren

Voorbeelden zijn:

  • alfabetische lijst van werknemers zonder te laat-record voor de prijs voor nul-te-laatheid
  • lijst met gebieden zonder klanten
  • lijst met verkoopagenten zonder verkoop van een bepaald product
  • resultaten krijgen van ontbrekende waarden, zoals datums zonder verkooporders in een bepaalde periode (voorbeeld hieronder)
  • knooppunten zonder kind in een ouder-kindrelatie (voorbeeld hieronder)

Resultaten krijgen van ontbrekende waarden

Stel dat u een rapport moet maken. Dat rapport moet het aantal dagen voor elke maand weergeven in een bepaalde periode waarin er geen bestellingen waren. De SalesOrderHeader in AdventureWorks bevat de OrderDates , maar ze hebben geen datums zonder bestellingen. Wat kunt u doen?

1. Maak een tabel met alle datums in een periode

Een voorbeeldscript hieronder maakt een tabel met datums voor heel 2014:

DECLARE @StartDate date = '20140101', @EndDate date = '20141231';

CREATE TABLE dbo.Dates
(
	d DATE NOT null PRIMARY KEY
)

WHILE @StartDate <= @EndDate
BEGIN
  INSERT Dates([d]) SELECT @StartDate;
  SET @StartDate = DATEADD(DAY, 1, @StartDate);
END

SELECT d FROM Dates ORDER BY [d];
2. Gebruik LEFT JOIN om de dagen zonder bestellingen uit te voeren
SELECT
 MONTH(d.d) AS [month]
,YEAR(d.d) AS [year]
,COUNT(*) AS NoOrderDays
FROM Dates d
LEFT JOIN Sales.SalesOrderHeader soh ON d.d = soh.OrderDate
WHERE soh.OrderDate IS NULL
GROUP BY YEAR(d.d), MONTH(d.d)
ORDER BY [year], [month]

Bovenstaande code telt het aantal dagen dat er geen bestellingen zijn gedaan. SalesOrderHeader bevat de data met bestellingen. Nulls die in de join worden geretourneerd, tellen dus als dagen zonder bestellingen.

Als u ondertussen de exacte datums wilt weten, kunt u de telling en groepering verwijderen.

SELECT
 d.d
,soh.OrderDate
FROM Dates d
LEFT JOIN Sales.SalesOrderHeader soh ON d.d = soh.OrderDate
WHERE soh.OrderDate IS NULL

Of, als u bestellingen in een bepaalde periode wilt tellen en wilt zien welke datum nul bestellingen heeft, gaat u als volgt te werk:

SELECT DISTINCT
 D.d AS SalesDate
,COUNT(soh.OrderDate) AS NoOfOrders
FROM Dates d
LEFT JOIN Sales.SalesOrderHeader soh ON d.d = soh.OrderDate
WHERE d.d BETWEEN '02/01/2014' AND '02/28/2014'
GROUP BY d.d
ORDER BY d.d

Bovenstaande code telt bestellingen voor februari 2014. Zie het resultaat:

Waarom wordt 3 februari 2014 gemarkeerd? In mijn exemplaar van AdventureWorks staan ​​geen verkooporders voor die datum.

Let nu op COUNT(soh.OrderDate) in de code. Later zullen we verduidelijken waarom dit zo belangrijk is.

Kinderloze nodes krijgen in ouder-kindrelaties

Soms moeten we de knooppunten zonder kind in een ouder-kindrelatie kennen.

Laten we de database gebruiken die ik heb gebruikt in mijn artikel over HierarchyID. Je moet nodes zonder kinderen in een parent-child relatietabel krijgen met behulp van een self-join.

SELECT 
 r1.RankParentId
,r1.Rank AS RankParent
,r.RankId
FROM Ranks r
RIGHT JOIN Ranks r1 ON r.RankParentId = r1.RankId
WHERE r.RankId is NULL 

Voorbehoud bij het gebruik van OUTER JOIN

Aangezien een OUTER JOIN binnenste rijen kan retourneren zoals een INNER JOIN, kan dit verwarrend zijn. Prestatieproblemen kunnen ook binnensluipen. Let dus op de 3 onderstaande punten (ik kom er af en toe op terug - ik word niet jonger, dus ik vergeet het ook).

De rechtertabel filteren in een LEFT JOIN met een niet-nullwaarde in de WHERE-clausule

Het kan een probleem zijn als je een LEFT OUTER JOIN hebt gebruikt, maar de juiste tabel hebt gefilterd met een niet-null-waarde in de WHERE-component. De reden is dat het functioneel equivalent wordt aan een INNER JOIN. Beschouw het onderstaande voorbeeld:

USE AdventureWorks
GO

SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
LEFT JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
LEFT JOIN Person.Address a ON bea.AddressID = a.AddressID
LEFT JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID
WHERE bea.AddressTypeID = 5 

Laten we uit de bovenstaande code de 2 tabellen bekijken:Persoon en BusinessEntityAddress . De persoon is de linkertabel, en BusinessEntityAddress is de juiste tafel.

LEFT JOIN wordt gebruikt, dus er wordt uitgegaan van een nul BusinessEntityID ergens in BusinessEntityAddress . Let hier op de WHERE-clausule. Het filtert de juiste tabel met AddressTypeID =5. Het verwijdert alle buitenste rijen in BusinessEntityAddress completely volledig .

Dit kan een van deze zijn:

  • De ontwikkelaar test iets in het resultaat, maar is vergeten het te verwijderen.
  • INNER JOIN was bedoeld, maar om de een of andere reden werd LEFT JOIN gebruikt.
  • De ontwikkelaar begrijpt het verschil tussen LEFT JOIN en INNER JOIN niet. Hij gaat ervan uit dat een van de twee zal werken, en dat maakt niet uit, want in dit geval zijn de resultaten hetzelfde.

Elk van de 3 hierboven is slecht, maar de derde invoer heeft een andere implicatie. Laten we de bovenstaande code vergelijken met het INNER JOIN-equivalent:

SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
INNER JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address a ON bea.AddressID = a.AddressID
INNER JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID
WHERE bea.AddressTypeID = 5

Het lijkt op de vorige code, behalve het type join. Het resultaat is ook hetzelfde, maar let op de logische waarden in STATISTICS IO:

In Afbeelding 7 zijn de eerste I/O-statistieken afkomstig van het gebruik van INNER JOIN. Het totaal aantal logische leesbewerkingen is 177. De tweede statistieken zijn echter voor de LEFT JOIN met een hogere logische leeswaarde van 223. Het verkeerde gebruik van LEFT JOIN in dit voorbeeld vereist dus meer pagina's of bronnen van SQL Server. Daarom zal het langzamer werken.

Afhaalmaaltijden

Als je van plan bent om binnenste rijen uit te voeren, gebruik dan INNER JOIN. Filter anders niet de rechtertabel in een LEFT JOIN met een niet-null-waarde. Als dit gebeurt, krijg je een langzamere zoekopdracht dan wanneer je INNER JOIN gebruikt.

BONUS TIP :Deze situatie doet zich ook voor in een RIGHT JOIN wanneer de linkertabel wordt gefilterd met een niet-null-waarde.

Onjuist gebruik van join-typen in een multi-join

Stel dat we alle . willen krijgen de leveranciers en het aantal productinkooporders voor elk. Hier is de code:

USE AdventureWorks
GO

SELECT
 v.BusinessEntityID
,v.Name AS Vendor
,pod.ProductID
,pod.OrderQty
FROM Purchasing.Vendor v
LEFT JOIN Purchasing.PurchaseOrderHeader poh ON v.BusinessEntityID = poh.VendorID
LEFT JOIN Purchasing.PurchaseOrderDetail pod ON poh.PurchaseOrderID = pod.PurchaseOrderID 

De bovenstaande code retourneert zowel de leveranciers met inkooporders als die zonder. Afbeelding 8 toont het werkelijke uitvoeringsplan van de bovenstaande code.

In de veronderstelling dat elke inkooporder een gegarandeerd inkooporderdetail heeft, zou een INNER JOIN beter zijn. Is het echter echt zo?

Laten we eerst de gewijzigde code hebben met de INNER JOIN.

USE AdventureWorks
GO

SELECT
 v.BusinessEntityID
,v.Name AS Vendor
,pod.ProductID
,pod.OrderQty
FROM Purchasing.Vendor v
LEFT JOIN Purchasing.PurchaseOrderHeader poh ON v.BusinessEntityID = poh.VendorID
INNER JOIN Purchasing.PurchaseOrderDetail pod ON poh.PurchaseOrderID = pod.PurchaseOrderID 

Onthoud dat de bovenstaande vereiste zegt "alle" leveranciers. Omdat we de LEFT JOIN in de vorige code hebben gebruikt, krijgen we leveranciers zonder inkooporders teruggestuurd. Dat komt door de null PurchaseOrderID .

Als u de join wijzigt in een INNER JOIN, worden alle null PurchaseOrderID's verwijderd. Het annuleert ook alle null VendorID's van de Verkoper tafel. In feite wordt het een INNER JOIN.

Is dat een juiste veronderstelling? Het uitvoeringsplan zal het antwoord onthullen:

Zoals je ziet zijn alle tabellen verwerkt met INNER JOIN. Onze veronderstelling is dus juist. Maar voor het ergste is de resultatenset nu onjuist omdat de leveranciers zonder bestellingen niet zijn opgenomen.

Afhaalmaaltijden

Net als in het vorige geval, als je een INNER JOIN van plan bent, gebruik deze dan. Maar je weet wat je moet doen als je een situatie als hier tegenkomt.

In dit geval zal een INNER JOIN alle buitenste rijen weggooien tot aan de bovenste tabel in de relatie. Zelfs als je andere join een LEFT JOIN is, maakt het niet uit. Dat hebben we bewezen in de Uitvoeringsplannen.

Onjuist gebruik van COUNT() in outer joins

Herinner je je onze voorbeeldcode die het aantal bestellingen per datum en het resultaat in figuur 6 telt?

Hier zullen we verduidelijken waarom 02/03/2014 is gemarkeerd en de relatie met COUNT(soh.OrderDate) .

Als u COUNT(*) probeert te gebruiken, wordt het aantal bestellingen voor die datum 1, wat niet klopt. Er zijn geen bestellingen op die datum. Dus, wanneer je COUNT() gebruikt met een OUTER JOIN, gebruik dan de juiste kolom om te tellen.

In ons geval, soh.OrderDate kan nul zijn of niet. Als het niet null is, neemt COUNT() de rij op in de telling. COUNT(*) zorgt ervoor dat alles wordt geteld, inclusief de nulls. En uiteindelijk verkeerde resultaten.

De OUTER JOIN afhaalrestaurants

Laten we de punten samenvatten:

  • OUTER JOIN kan zowel binnenste rijen als buitenste rijen retourneren. Binnenste rijen zijn het resultaat dat vergelijkbaar is met het resultaat van INNER JOIN. De buitenste rijen zijn de niet-null-waarden met hun null-tegenhangers op basis van de join-voorwaarde.
  • OUTER JOIN kan LINKS, RECHTS of VOLLEDIG zijn. We hadden voorbeelden voor elk.
  • De buitenste rijen die door OUTER JOIN worden geretourneerd, kunnen op verschillende praktische manieren worden gebruikt. We hadden ideeën over wanneer je dit spul kunt gebruiken.
  • We hadden ook kanttekeningen bij het gebruik van OUTER JOIN. Houd rekening met de 3 bovenstaande punten om bugs en prestatieproblemen te voorkomen.

Het laatste deel van deze serie gaat over CROSS JOIN. Dus tot dan. En als je dit bericht leuk vindt, deel dan wat liefde door op de social media-knoppen te klikken. Veel plezier met coderen!


  1. Oracle-update loopt vast

  2. Algemene Postgres-taken op CentOS 7

  3. SQL Server:moet ik information_schema-tabellen gebruiken in plaats van sys-tabellen?

  4. MySQL Selecteer alle kolommen uit de ene tabel en enkele uit een andere tabel