Deel 1 - Toetredingen en vakbonden
Dit antwoord omvat:
- Deel 1
- Twee of meer tabellen samenvoegen met een inner join (zie het wikipedia-item voor meer info)
- Een samenvoegquery gebruiken
- Links en rechts buitenste joins (dit stackOverflow-antwoord is uitstekend om typen joins te beschrijven)
- Query's doorsnijden (en hoe u ze kunt reproduceren als uw database ze niet ondersteunt) - dit is een functie van SQL-Server (zie info ) en een deel van de reden waarom ik dit hele ding heb geschreven in de eerste plaats.
- Deel 2
- Subquery's - wat ze zijn, waar ze kunnen worden gebruikt en waar je op moet letten
- Cartesian sluit zich aan bij AKA - Oh, de ellende!
Er zijn een aantal manieren om gegevens uit meerdere tabellen in een database op te halen. In dit antwoord zal ik de syntaxis van ANSI-92 gebruiken. Dit kan verschillen van een aantal andere tutorials die de oudere ANSI-89-syntaxis gebruiken (en als je gewend bent aan 89, lijkt het misschien veel minder intuïtief - maar alles wat ik kan zeggen is om het te proberen) zoals het is veel gemakkelijker te begrijpen wanneer de vragen complexer worden. Waarom het gebruiken? Is er prestatiewinst? Het korte antwoord is nee, maar het is is leest makkelijker als je er eenmaal aan gewend bent. Het is gemakkelijker om zoekopdrachten te lezen die zijn geschreven door andere mensen die deze syntaxis gebruiken.
Ik ga ook het concept van een kleine garage gebruiken die een database heeft om bij te houden welke auto's beschikbaar zijn. De eigenaar heeft je ingehuurd als zijn IT-computerman en verwacht dat je hem in een mum van tijd de gegevens kunt bezorgen waar hij om vraagt.
Ik heb een aantal opzoektabellen gemaakt die door de finaletafel zullen worden gebruikt. Dit geeft ons een redelijk model om vanuit te werken. Om te beginnen zal ik mijn query's uitvoeren op een voorbeelddatabase met de volgende structuur. Ik zal proberen veelgemaakte fouten te bedenken die bij het begin worden gemaakt en uit te leggen wat er mis gaat - en natuurlijk ook laten zien hoe ze te corrigeren.
De eerste tabel is gewoon een kleurenlijst, zodat we weten welke kleuren we in de autostalling hebben.
mysql> create table colors(id int(3) not null auto_increment primary key,
-> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | varchar(15) | YES | | NULL | |
| paint | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> insert into colors (color, paint) values ('Red', 'Metallic'),
-> ('Green', 'Gloss'), ('Blue', 'Metallic'),
-> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from colors;
+----+-------+----------+
| id | color | paint |
+----+-------+----------+
| 1 | Red | Metallic |
| 2 | Green | Gloss |
| 3 | Blue | Metallic |
| 4 | White | Gloss |
| 5 | Black | Gloss |
+----+-------+----------+
5 rows in set (0.00 sec)
De merkentabel identificeert de verschillende merken van de auto's die de garage mogelijk zou kunnen verkopen.
mysql> create table brands (id int(3) not null auto_increment primary key,
-> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| brand | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
mysql> insert into brands (brand) values ('Ford'), ('Toyota'),
-> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from brands;
+----+--------+
| id | brand |
+----+--------+
| 1 | Ford |
| 2 | Toyota |
| 3 | Nissan |
| 4 | Smart |
| 5 | BMW |
+----+--------+
5 rows in set (0.00 sec)
De modeltabel zal betrekking hebben op verschillende soorten auto's, het wordt hierdoor eenvoudiger om verschillende autotypes te gebruiken in plaats van echte automodellen.
mysql> create table models (id int(3) not null auto_increment primary key,
-> model varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| model | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from models;
+----+--------+
| id | model |
+----+--------+
| 1 | Sports |
| 2 | Sedan |
| 3 | 4WD |
| 4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)
En tot slot, om al die andere tafels aan elkaar te knopen, de tafel die alles samenbindt. Het ID-veld is eigenlijk het unieke lotnummer dat wordt gebruikt om auto's te identificeren.
mysql> create table cars (id int(3) not null auto_increment primary key,
-> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | int(3) | YES | | NULL | |
| brand | int(3) | YES | | NULL | |
| model | int(3) | YES | | NULL | |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1),
-> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
| 1 | 1 | 2 | 1 |
| 2 | 3 | 1 | 2 |
| 3 | 5 | 3 | 1 |
| 4 | 4 | 4 | 2 |
| 5 | 2 | 2 | 3 |
| 6 | 3 | 5 | 4 |
| 7 | 4 | 1 | 3 |
| 8 | 2 | 2 | 1 |
| 9 | 5 | 2 | 3 |
| 10 | 4 | 5 | 1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)
Dit geeft ons genoeg gegevens (hoop ik) om de onderstaande voorbeelden van verschillende soorten joins te verdoezelen en ook genoeg gegevens om ze de moeite waard te maken.
Dus om er helemaal in te gaan, wil de baas weten De ID's van alle sportwagens die hij heeft .
Dit is een eenvoudige join met twee tabellen. We hebben een tabel die het model identificeert en de tafel met de beschikbare voorraad erin. Zoals u kunt zien, zijn de gegevens in het model
kolom van de cars
tabel heeft betrekking op de models
kolom van de cars
tafel die we hebben. Nu weten we dat de modellentabel een ID heeft van 1
voor Sports
dus laten we de join schrijven.
select
ID,
model
from
cars
join models
on model=ID
Dus deze query ziet er goed uit toch? We hebben de twee tabellen geïdentificeerd en bevatten de informatie die we nodig hebben en gebruiken een join die correct identificeert aan welke kolommen we moeten deelnemen.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
Oh nee! Een fout in onze eerste zoekopdracht! Ja, en het is een pruim. De query heeft inderdaad de juiste kolommen, maar sommige staan in beide tabellen, dus de database raakt in de war over welke kolom we bedoelen en waar. Er zijn twee oplossingen om dit op te lossen. De eerste is leuk en eenvoudig, we kunnen tableName.columnName
. gebruiken om de database precies te vertellen wat we bedoelen, als volgt:
select
cars.ID,
models.model
from
cars
join models
on cars.model=models.ID
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
| 2 | Sedan |
| 4 | Sedan |
| 5 | 4WD |
| 7 | 4WD |
| 9 | 4WD |
| 6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)
De andere wordt waarschijnlijk vaker gebruikt en wordt tabelaliasing genoemd. De tabellen in dit voorbeeld hebben mooie en korte eenvoudige namen, maar typ iets als KPI_DAILY_SALES_BY_DEPARTMENT
zou waarschijnlijk snel oud worden, dus een eenvoudige manier is om de tafel als volgt een bijnaam te geven:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
Nu terug naar het verzoek. Zoals je kunt zien, hebben we de informatie die we nodig hebben, maar we hebben ook informatie waar niet om is gevraagd, dus we moeten een waar-clausule in de verklaring opnemen om alleen de sportwagens te krijgen zoals gevraagd. Omdat ik de voorkeur geef aan de tabelaliasmethode in plaats van de tabelnamen steeds opnieuw te gebruiken, zal ik me er vanaf dit punt aan houden.
Het is duidelijk dat we een waar-clausule aan onze query moeten toevoegen. We kunnen sportwagens identificeren aan de hand van ID=1
of model='Sports'
. Omdat de ID is geïndexeerd en de primaire sleutel (en het is minder typen), laten we die gebruiken in onze zoekopdracht.
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
Bingo! De baas is blij. Natuurlijk, als baas en nooit tevreden met wat hij vroeg, kijkt hij naar de informatie en zegt dan Ik wil ook de kleuren .
Oké, dus we hebben een groot deel van onze query al geschreven, maar we moeten een derde tabel gebruiken die kleuren is. Nu, onze hoofdinformatietabel cars
slaat de kleur-ID van de auto op en deze linkt terug naar de kolom met de kleuren-ID. Dus, op een gelijkaardige manier als het origineel, kunnen we deelnemen aan een derde tafel:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
Verdorie, hoewel de tabel correct was samengevoegd en de gerelateerde kolommen waren gekoppeld, waren we vergeten de daadwerkelijke informatie in te voeren uit de nieuwe tabel die we zojuist hebben gekoppeld.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)
Juist, dat is even de baas van ons af. Nu, om het een en ander in meer detail uit te leggen. Zoals je kunt zien, is de from
clausule in onze verklaring verbindt onze hoofdtabel (ik gebruik vaak een tabel die informatie bevat in plaats van een opzoek- of dimensietabel. De query zou net zo goed werken als de tabellen allemaal omgedraaid zijn, maar heeft minder zin als we terugkomen op deze query om het in een paar maanden te lezen, dus het is vaak het beste om te proberen een vraag te schrijven die leuk en gemakkelijk te begrijpen is - leg het intuïtief uit, gebruik mooie inspringingen zodat alles zo duidelijk mogelijk is. ga door met het onderwijzen van anderen, probeer deze kenmerken in hun vragen in te voeren - vooral als je ze gaat oplossen.
Het is heel goed mogelijk om op deze manier steeds meer tabellen te blijven koppelen.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
Hoewel ik vergat een tabel op te nemen waarin we mogelijk meer dan één kolom willen toevoegen in de join
verklaring, hier is een voorbeeld. Als de models
tabel had merkspecifieke modellen en had daarom ook een kolom met de naam brand
die terug linkten naar de brands
tabel op de ID
veld, kan het als volgt worden gedaan:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
and b.brand=d.ID
where
b.ID=1
U kunt zien dat de bovenstaande zoekopdracht niet alleen de samengevoegde tabellen koppelt aan de belangrijkste cars
table, maar specificeert ook joins tussen de reeds samengevoegde tabellen. Als dit niet is gebeurd, wordt het resultaat een cartesiaanse join genoemd - wat een slechte zaak is. Een cartesiaanse join is er een waarbij rijen worden geretourneerd omdat de informatie de database niet vertelt hoe de resultaten moeten worden beperkt, dus de query retourneert alle de rijen die aan de criteria voldoen.
Dus, om een voorbeeld te geven van een cartesiaanse join, laten we de volgende query uitvoeren:
select
a.ID,
b.model
from
cars a
join models b
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 1 | Sedan |
| 1 | 4WD |
| 1 | Luxury |
| 2 | Sports |
| 2 | Sedan |
| 2 | 4WD |
| 2 | Luxury |
| 3 | Sports |
| 3 | Sedan |
| 3 | 4WD |
| 3 | Luxury |
| 4 | Sports |
| 4 | Sedan |
| 4 | 4WD |
| 4 | Luxury |
| 5 | Sports |
| 5 | Sedan |
| 5 | 4WD |
| 5 | Luxury |
| 6 | Sports |
| 6 | Sedan |
| 6 | 4WD |
| 6 | Luxury |
| 7 | Sports |
| 7 | Sedan |
| 7 | 4WD |
| 7 | Luxury |
| 8 | Sports |
| 8 | Sedan |
| 8 | 4WD |
| 8 | Luxury |
| 9 | Sports |
| 9 | Sedan |
| 9 | 4WD |
| 9 | Luxury |
| 10 | Sports |
| 10 | Sedan |
| 10 | 4WD |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)
Goeie god, dat is lelijk. Wat de database betreft, is het echter precies waar werd om gevraagd. In de zoekopdracht hebben we gevraagd om de ID
van cars
en het model
van models
. Omdat we echter niet hebben gespecificeerd hoe om de tabellen samen te voegen, heeft de database elke rij vanaf de eerste tafel met elke rij van de tweede tafel.
Oké, dus de baas is terug en hij wil weer meer informatie. Ik wil dezelfde lijst, maar er ook 4WD's in opnemen .
Dit geeft ons echter een goed excuus om naar twee verschillende manieren te kijken om dit te bereiken. We zouden een andere voorwaarde kunnen toevoegen aan de waar-clausule als volgt:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
or b.ID=3
Hoewel het bovenstaande perfect zal werken, laten we het anders bekijken, is dit een geweldig excuus om te laten zien hoe een union
query zal werken.
We weten dat het volgende alle sportwagens zal teruggeven:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
En het volgende zou alle 4WD's retourneren:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
Dus door een union all
. toe te voegen clausule ertussen, worden de resultaten van de tweede zoekopdracht toegevoegd aan de resultaten van de eerste zoekopdracht.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
union all
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
| 5 | 4WD | Green |
| 7 | 4WD | White |
| 9 | 4WD | Black |
+----+--------+-------+
7 rows in set (0.00 sec)
Zoals u kunt zien, worden eerst de resultaten van de eerste zoekopdracht geretourneerd, gevolgd door de resultaten van de tweede zoekopdracht.
In dit voorbeeld was het natuurlijk veel gemakkelijker geweest om gewoon de eerste zoekopdracht te gebruiken, maar union
query's kunnen geweldig zijn voor specifieke gevallen. Ze zijn een geweldige manier om specifieke resultaten te retourneren van tabellen van tabellen die niet gemakkelijk aan elkaar te koppelen zijn - of wat dat betreft volledig niet-gerelateerde tabellen. Er zijn echter een paar regels die u moet volgen.
- De kolomtypen van de eerste zoekopdracht moeten overeenkomen met de kolomtypen van elke andere zoekopdracht hieronder.
- De namen van de kolommen uit de eerste zoekopdracht worden gebruikt om de volledige reeks resultaten te identificeren.
- Het aantal kolommen in elke zoekopdracht moet hetzelfde zijn.
Nu vraag je je misschien de
verschil is tussen het gebruik van union
en union all
. Een union
query zal duplicaten verwijderen, terwijl een union all
zal niet. Dit betekent wel dat er een kleine prestatiehit is bij het gebruik van union
over union all
maar de resultaten zijn misschien de moeite waard - ik zal hier echter niet over speculeren.
Bij deze opmerking is het misschien de moeite waard om hier enkele aanvullende opmerkingen te maken.
- Als we de resultaten willen bestellen, kunnen we een
order by
. gebruiken maar je kunt de alias niet meer gebruiken. Voeg in de bovenstaande zoekopdracht eenorder by a.ID
zou resulteren in een fout - wat de resultaten betreft, heet de kolomID
in plaats vana.ID
- ook al is in beide zoekopdrachten dezelfde alias gebruikt. - We kunnen slechts één
order by
verklaring, en het moet als de laatste verklaring zijn.
Voor de volgende voorbeelden voeg ik een paar extra rijen toe aan onze tabellen.
Ik heb Holden
toegevoegd aan de merkentabel. Ik heb ook een rij toegevoegd aan cars
die de color
. heeft waarde van 12
- die geen verwijzing heeft in de kleurentabel.
Oké, de baas is weer terug, blaffende verzoeken - *Ik wil een telling van elk merk dat we voeren en het aantal auto's erin!' - Typisch, we komen gewoon bij een interessant deel van onze discussie en de baas wil meer werk .
Juist, dus het eerste dat we moeten doen, is een volledige lijst van mogelijke merken krijgen.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
Als we dit nu samenvoegen met onze autotabel, krijgen we het volgende resultaat:
select
a.brand
from
brands a
join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Nissan |
| Smart |
| Toyota |
+--------+
5 rows in set (0.00 sec)
Wat natuurlijk een probleem is - we zien geen enkele vermelding van de mooie Holden
merk dat ik heb toegevoegd.
Dit komt omdat een join zoekt naar overeenkomende rijen in beide tafels. Aangezien er geen gegevens zijn in auto's van het type Holden
het wordt niet geretourneerd. Hier kunnen we een outer
. gebruiken meedoen. Hiermee wordt alle geretourneerd de resultaten van de ene tabel, of ze nu overeenkomen in de andere tabel of niet:
select
a.brand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Holden |
| Nissan |
| Smart |
| Toyota |
+--------+
6 rows in set (0.00 sec)
Nu we dat hebben, kunnen we een mooie aggregatiefunctie toevoegen om een telling te krijgen en de baas even van ons af te zetten.
select
a.brand,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+--------------+
| brand | countOfBrand |
+--------+--------------+
| BMW | 2 |
| Ford | 2 |
| Holden | 0 |
| Nissan | 1 |
| Smart | 1 |
| Toyota | 5 |
+--------+--------------+
6 rows in set (0.00 sec)
En daarmee sluipt de baas weg.
Om dit wat meer in detail uit te leggen, kunnen outer joins van de left
. zijn of right
type. Links of Rechts bepaalt welke tafel volledig is inbegrepen. Een left outer join
zal alle rijen uit de tabel aan de linkerkant bevatten, terwijl (je raadt het al) een right outer join
brengt alle resultaten uit de tabel aan de rechterkant in de resultaten.
Sommige databases staan een full outer join
toe die resultaten oplevert (al dan niet overeenkomend) van beide tabellen, maar dit wordt niet in alle databases ondersteund.
Nu, ik denk dat je je op dit moment waarschijnlijk afvraagt of je join-types in een query kunt samenvoegen - en het antwoord is ja, dat kan absoluut.
select
b.brand,
c.color,
count(a.id) as countOfBrand
from
cars a
right outer join brands b
on b.ID=a.brand
join colors c
on a.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| Ford | Blue | 1 |
| Ford | White | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| BMW | Blue | 1 |
| BMW | White | 1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)
Dus waarom zijn dat niet de verwachte resultaten? De reden is dat, hoewel we de buitenste join van auto's tot merken hebben geselecteerd, deze niet is gespecificeerd in de join met kleuren - dus die bepaalde join levert alleen resultaten op die in beide tabellen overeenkomen.
Hier is de query die zou werken om de resultaten te krijgen die we verwachtten:
select
a.brand,
c.color,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
left outer join colors c
on b.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| BMW | Blue | 1 |
| BMW | White | 1 |
| Ford | Blue | 1 |
| Ford | White | 1 |
| Holden | NULL | 0 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| Toyota | NULL | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)
Zoals we kunnen zien, hebben we twee outer joins in de query en de resultaten komen door zoals verwacht.
Hoe zit het met die andere soorten joins die je vraagt? Hoe zit het met kruispunten?
Welnu, niet alle databases ondersteunen het intersection
maar in vrijwel alle databases kun je een kruising maken via een join (of op zijn minst een goed gestructureerd waar-statement).
Een Intersection is een type join dat enigszins lijkt op een union
zoals hierboven beschreven - maar het verschil is dat het alleen retourneert rijen met gegevens die identiek zijn (en ik bedoel identiek) tussen de verschillende individuele query's die door de unie zijn samengevoegd. Alleen rijen die in elk opzicht identiek zijn, worden geretourneerd.
Een eenvoudig voorbeeld zou als volgt zijn:
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
Terwijl een normale union
query retourneert alle rijen van de tabel (de eerste query retourneert iets meer dan ID>2
en de tweede alles met ID<4
) wat zou resulteren in een volledige set, zou een intersect-query alleen de rij retourneren die overeenkomt met id=3
omdat het aan beide criteria voldoet.
Als uw database nu geen intersect
ondersteunt, vraag, kan het bovenstaande eenvoudig worden bereikt met de volgende vraag:
select
a.ID,
a.color,
a.paint
from
colors a
join colors b
on a.ID=b.ID
where
a.ID>2
and b.ID<4
+----+-------+----------+
| ID | color | paint |
+----+-------+----------+
| 3 | Blue | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)
Als u een intersectie wilt uitvoeren over twee verschillende tabellen met behulp van een database die niet inherent een intersectiequery ondersteunt, moet u een join maken op elke kolom van de tafels.