Del 1 - Sammenslutninger og fagforeninger
Dette svar dækker:
- Del 1
- Samling af to eller flere tabeller ved hjælp af en indre joinforbindelse (se wikipedia-indlægget a> for yderligere oplysninger)
- Sådan bruger du en fagforeningsforespørgsel
- Venstre og højre ydre sammenføjninger (dette stackOverflow-svar er fremragende til at beskrive typer af joinforbindelser)
- Skæringsforespørgsler (og hvordan man gengiver dem, hvis din database ikke understøtter dem) - dette er en funktion af SQL-Server (se info ) og en del af grund til, at jeg skrev det hele i første omgang.
- Del 2
- Underforespørgsler - hvad de er, hvor de kan bruges, og hvad skal man være opmærksom på
- Cartesian slutter sig til AKA - Åh, elendigheden!
Der er en række måder at hente data fra flere tabeller i en database. I dette svar vil jeg bruge ANSI-92 join-syntaks. Dette kan være anderledes end en række andre tutorials derude, som bruger den ældre ANSI-89 syntaks (og hvis du er vant til 89, kan det virke meget mindre intuitivt - men alt, hvad jeg kan sige er at prøve det), som det er meget nemmere at forstå, når forespørgslerne begynder at blive mere komplekse. Hvorfor bruge det? Er der en præstationsgevinst? Det korte svar er nej, men det er nemmere at læse, når du har vænnet dig til det. Det er lettere at læse forespørgsler skrevet af andre, der bruger denne syntaks.
Jeg vil også bruge konceptet med et lille caryard, som har en database til at holde styr på, hvilke biler den har til rådighed. Ejeren har ansat dig som sin IT-computer og forventer, at du kan aflevere ham de data, han beder om, med det samme.
Jeg har lavet en række opslagstabeller, som skal bruges af finalebordet. Dette vil give os en rimelig model at arbejde ud fra. Til at starte med vil jeg køre mine forespørgsler mod en eksempeldatabase, der har følgende struktur. Jeg vil prøve at tænke på almindelige fejl, der begås, når man starter og forklare, hvad der går galt med dem - samt selvfølgelig vise, hvordan man retter dem.
Den første tabel er simpelthen en farveliste, så vi ved, hvilke farver vi har i bilgården.
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)
Mærketabellen identificerer de forskellige mærker af de biler, som caryard muligvis kan sælge.
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)
Modeltabellen vil dække forskellige typer biler, det bliver nemmere for dette at bruge forskellige biltyper frem for egentlige bilmodeller.
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)
Og til sidst, for at binde alle disse andre borde, bordet der binder alt sammen. ID-feltet er faktisk det unikke partinummer, der bruges til at identificere biler.
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)
Dette vil give os nok data (håber jeg) til at dække nedenstående eksempler på forskellige typer joinforbindelser og også give nok data til at gøre dem umagen værd.
Så når chefen kommer ind i det, vil han gerne vide ID'erne for alle de sportsvogne, han har .
Dette er en simpel sammenføjning med to tabeller. Vi har en tabel, der identificerer modellen og bordet med det tilgængelige lager i. Som du kan se, er dataene i model
kolonne af cars
tabel relaterer til models
kolonne af cars
bord vi har. Nu ved vi, at modeltabellen har et ID på 1
til Sports
så lad os skrive sammenføjningen.
select
ID,
model
from
cars
join models
on model=ID
Så denne forespørgsel ser godt ud, ikke? Vi har identificeret de to tabeller og indeholder de oplysninger, vi har brug for, og bruger en joinforbindelse, der korrekt identificerer, hvilke kolonner der skal tilsluttes.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
Åh nej! En fejl i vores første forespørgsel! Ja, og det er en blomme. Du kan se, forespørgslen har faktisk fået de rigtige kolonner, men nogle af dem findes i begge tabeller, så databasen bliver forvirret over, hvilken kolonne vi mener, og hvor. Der er to løsninger til at løse dette. Den første er fin og enkel, vi kan bruge tableName.columnName
at fortælle databasen præcis, hvad vi mener, sådan her:
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)
Den anden bruges nok oftere og kaldes table aliasing. Tabellerne i dette eksempel har fine og korte enkle navne, men skriver noget som KPI_DAILY_SALES_BY_DEPARTMENT
ville sandsynligvis hurtigt blive gammel, så en enkel måde er at kalde tabellen sådan her:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
Nu tilbage til anmodningen. Som du kan se, har vi de oplysninger, vi har brug for, men vi har også oplysninger, der ikke blev bedt om, så vi skal inkludere en hvor-klausul i erklæringen for kun at få de sportsvogne, som blev bedt om. Da jeg foretrækker tabelaliasmetoden frem for at bruge tabelnavnene igen og igen, vil jeg holde mig til den fra dette tidspunkt og fremefter.
Det er klart, at vi skal tilføje en where-klausul til vores forespørgsel. Vi kan identificere sportsvogne enten ved ID=1
eller model='Sports'
. Da ID'et er indekseret og den primære nøgle (og det tilfældigvis er mindre skrivning), lad os bruge det i vores forespørgsel.
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! Chefen er glad. Når han er chef og aldrig er tilfreds med det, han bad om, kigger han selvfølgelig på informationen og siger derefter Jeg vil også have farverne .
Okay, så vi har allerede skrevet en god del af vores forespørgsel, men vi skal bruge en tredje tabel, som er farver. Nu, vores vigtigste informationstabel cars
gemmer bilens farve-id, og dette linker tilbage til kolonnen for farver-id. Så på samme måde som originalen kan vi slutte os til en tredje tabel:
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)
For fanden, selvom tabellen var korrekt sammenføjet, og de relaterede kolonner var forbundet, glemte vi at hente de faktiske oplysninger fra den nye tabel, som vi lige har linket.
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)
Okay, det er chefen fra vores ryg et øjeblik. For nu at forklare noget af dette lidt mere detaljeret. Som du kan se, er from
klausul i vores sætning forbinder vores hovedtabel (jeg bruger ofte en tabel, der indeholder information i stedet for en opslags- eller dimensionstabel. Forespørgslen ville fungere lige så godt med tabellerne skiftet rundt, men giver mindre mening, når vi vender tilbage til denne forespørgsel at læse den om nogle måneder, så det er ofte bedst at prøve at skrive en forespørgsel, der vil være god og nem at forstå - læg den intuitivt ud, brug pæne indrykning, så alt er så tydeligt, som det kan blive. fortsæt med at lære andre, prøv at indgyde disse egenskaber i deres forespørgsler - især hvis du skal fejlfinde dem.
Det er fuldt ud muligt at blive ved med at linke flere og flere tabeller på denne måde.
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
Mens jeg glemte at inkludere en tabel, hvor vi måske ønsker at forbinde mere end én kolonne i join
erklæring, her er et eksempel. Hvis models
tabellen havde mærkespecifikke modeller og havde derfor også en kolonne kaldet brand
som linkede tilbage til brands
tabel på ID
felt, kunne det gøres som dette:
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
Du kan se, at forespørgslen ovenfor ikke kun linker de sammenføjede tabeller til de vigtigste cars
tabel, men angiver også sammenkædninger mellem de allerede sammenføjede tabeller. Hvis dette ikke blev gjort, kaldes resultatet en kartesisk join - hvilket er dba speak for bad. En kartesisk joinforbindelse er en, hvor rækker returneres, fordi oplysningerne ikke fortæller databasen, hvordan resultaterne skal begrænses, så forespørgslen returnerer alle de rækker, der passer til kriterierne.
Så for at give et eksempel på en kartesisk join, lad os køre følgende forespørgsel:
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)
Gode gud, det er grimt. Men hvad databasen angår, er den præcis hvad der blev bedt om. I forespørgslen bad vi om ID
fra cars
og model
fra models
. Men fordi vi ikke specificerede hvordan For at deltage i tabellerne har databasen matchet alle række fra den første tabel med hver række fra den anden tabel.
Okay, så chefen er tilbage, og han vil have mere information igen. Jeg vil have den samme liste, men også inkludere 4WD'er i den .
Dette giver os dog en god undskyldning for at se på to forskellige måder at opnå dette på. Vi kunne tilføje en anden betingelse til where-sætningen som denne:
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
Selvom ovenstående vil fungere perfekt, lad os se på det anderledes, dette er en god undskyldning for at vise, hvordan en union
forespørgslen vil virke.
Vi ved, at følgende vil returnere alle sportsvognene:
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
Og følgende ville returnere alle 4WD'erne:
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
Så ved at tilføje en union all
klausul mellem dem, vil resultaterne af den anden forespørgsel blive tilføjet til resultaterne af den første forespørgsel.
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)
Som du kan se, returneres resultaterne af den første forespørgsel først, efterfulgt af resultaterne af den anden forespørgsel.
I dette eksempel ville det selvfølgelig have været meget nemmere blot at bruge den første forespørgsel, men union
forespørgsler kan være gode til specifikke tilfælde. De er en fantastisk måde at returnere specifikke resultater fra tabeller fra tabeller, der ikke nemt kan sættes sammen - eller for den sags skyld helt urelaterede tabeller. Der er dog et par regler, der skal følges.
- Kolonnetyperne fra den første forespørgsel skal matche kolonnetyperne fra hver anden forespørgsel nedenfor.
- Navnene på kolonnerne fra den første forespørgsel vil blive brugt til at identificere hele sæt resultater.
- Antallet af kolonner i hver forespørgsel skal være det samme.
Nu kan du undre dig over, hvad den
forskellen er mellem at bruge union
og union all
. En union
forespørgsel vil fjerne dubletter, mens en union all
vil ikke. Dette betyder, at der er et lille præstationshit, når du bruger union
over union all
men resultaterne kan være det værd - jeg vil dog ikke spekulere i den slags i dette.
På denne note kan det være værd at bemærke nogle yderligere noter her.
- Hvis vi ønskede at bestille resultaterne, kan vi bruge en
order by
men du kan ikke bruge aliaset længere. I forespørgslen ovenfor, tilføjelse af enorder by a.ID
ville resultere i en fejl - hvad resultaterne angår, hedder kolonnenID
i stedet fora.ID
- selvom det samme alias er blevet brugt i begge forespørgsler. - Vi kan kun have én
order by
sætning, og den skal være som den sidste erklæring.
Til de næste eksempler tilføjer jeg et par ekstra rækker til vores tabeller.
Jeg har tilføjet Holden
til mærketabellen. Jeg har også tilføjet en række i cars
der har color
værdi af 12
- som ikke har nogen reference i farvetabellen.
Okay, chefen er tilbage igen, gøende anmodninger ud - *Jeg vil have en optælling af hvert mærke, vi fører, og antallet af biler i det!` - Typisk kommer vi bare til et interessant afsnit af vores diskussion, og chefen vil have mere arbejde .
Okay, så det første vi skal gøre er at få en komplet liste over mulige mærker.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
Nu, når vi tilføjer dette til vores biler tabel, får vi følgende resultat:
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)
Hvilket selvfølgelig er et problem - vi kan ikke se nogen omtale af den dejlige Holden
mærke, jeg tilføjede.
Dette skyldes, at en join søger efter matchende rækker i begge tabeller. Da der ikke er data i biler, der er af typen Holden
det bliver ikke returneret. Det er her, vi kan bruge en outer
tilslutte. Dette vil returnere alle resultaterne fra den ene tabel, uanset om de matches i den anden tabel eller ej:
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 hvor vi har det, kan vi tilføje en dejlig aggregeret funktion for at få en optælling og få chefen væk fra ryggen et øjeblik.
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)
Og med det, væk chefen skulker.
For nu at forklare dette mere detaljeret, kan ydre joinforbindelser være til left
eller right
type. Venstre eller Højre definerer, hvilken tabel der er fuldstændig inkluderet. En left outer join
vil inkludere alle rækkerne fra tabellen til venstre, mens (du gættede det) en right outer join
bringer alle resultaterne fra tabellen til højre ind i resultaterne.
Nogle databaser tillader en full outer join
som vil bringe resultater tilbage (uanset om de matches eller ej) fra begge tabeller, men dette understøttes ikke i alle databaser.
Nu tænker jeg nok på dette tidspunkt, at du spekulerer på, om du kan flette jointyper i en forespørgsel - og svaret er ja, det kan du absolut.
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)
Så hvorfor er det ikke de resultater, der var forventet? Det skyldes, at selvom vi har valgt den ydre sammenføjning fra biler til mærker, var den ikke specificeret i sammenføjningen til farver - så den pågældende sammenføjning vil kun give resultater, der matcher i begge tabeller.
Her er forespørgslen, der ville arbejde for at få de resultater, vi forventede:
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)
Som vi kan se, har vi to ydre joinforbindelser i forespørgslen, og resultaterne kommer igennem som forventet.
Hvad med de andre typer joinforbindelser, spørger du? Hvad med Intersections?
Nå, ikke alle databaser understøtter intersection
men stort set alle databaser giver dig mulighed for at skabe et skæringspunkt gennem en joinforbindelse (eller en velstruktureret where-sætning i det mindste).
Et kryds er en type joinforbindelse, der ligner en union
som beskrevet ovenfor - men forskellen er, at det kun returnerer rækker af data, der er identiske (og jeg mener identiske) mellem de forskellige individuelle forespørgsler, som fagforeningen tilslutter sig. Kun rækker, der er identiske i enhver henseende, vil blive returneret.
Et simpelt eksempel ville være som sådan:
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
Mens en normal union
forespørgsel ville returnere alle rækkerne i tabellen (den første forespørgsel returnerer noget over ID>2
og den anden noget med ID<4
), hvilket ville resultere i et komplet sæt, ville en skærende forespørgsel kun returnere den række, der matcher id=3
da den opfylder begge kriterier.
Nu, hvis din database ikke understøtter en intersect
forespørgsel, kan ovenstående nemt udføres med følgende forespørgsel:
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)
Hvis du ønsker at udføre et kryds på tværs af to forskellige tabeller ved hjælp af en database, der ikke i sagens natur understøtter en krydsningsforespørgsel, skal du oprette en joinforbindelse på hver kolonne af tabellerne.