Del 1 - Går med och fackföreningar
Det här svaret omfattar:
- Del 1
- Ansluta två eller flera tabeller med en inre sammanfogning (se wikipedia-inlägget a> för ytterligare information)
- Hur man använder en facklig fråga
- vänster och höger yttre kopplingar (detta stackOverflow-svar är utmärkt för att beskriva typer av anslutningar)
- Skär frågor (och hur man återskapar dem om din databas inte stöder dem) - detta är en funktion av SQL-Server (se info ) och en del av anledning till att jag skrev hela den här grejen i första hand.
- Del 2
- Undersökningar – vad de är, var de kan användas och vad man ska se upp med
- Cartesian ansluter sig till AKA - Åh, eländet!
Det finns ett antal sätt att hämta data från flera tabeller i en databas. I det här svaret kommer jag att använda ANSI-92 join-syntax. Detta kan skilja sig från ett antal andra tutorials där ute som använder den äldre ANSI-89-syntaxen (och om du är van vid 89 kan det verka mycket mindre intuitivt - men allt jag kan säga är att prova det) som det är mycket lättare att förstå när frågorna börjar bli mer komplexa. Varför använda det? Finns det en prestationsvinst? Det korta svaret är nej, men det är lättare att läsa när du vant dig. Det är lättare att läsa frågor skrivna av andra som använder den här syntaxen.
Jag ska också använda konceptet med en liten bilgård som har en databas för att hålla reda på vilka bilar den har tillgängliga. Ägaren har anställt dig som sin IT-datorkille och förväntar sig att du ska kunna lämna honom den information som han ber om med en gång.
Jag har gjort ett antal uppslagstabeller som kommer att användas av finalbordet. Detta kommer att ge oss en rimlig modell att arbeta utifrån. Till att börja med kommer jag att köra mina frågor mot en exempeldatabas som har följande struktur. Jag ska försöka tänka på vanliga misstag som görs när man börjar och förklara vad som går fel med dem - samt naturligtvis visa hur man rättar till dem.
Den första tabellen är helt enkelt en färglista så att vi vet vilka färger vi har på 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ärkestabellen identifierar de olika märkena av de bilar som bilgården kan sälja.
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)
Modelltabellen kommer att täcka olika typer av bilar, det kommer att bli enklare för detta att använda olika biltyper snarare än faktiska 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)
Och slutligen, för att knyta ihop alla dessa andra bord, bordet som binder ihop allt. ID-fältet är faktiskt det unika partinumret som används för att identifiera bilar.
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)
Detta kommer att ge oss tillräckligt med data (hoppas jag) för att täcka exemplen nedan på olika typer av sammanfogningar och även ge tillräckligt med data för att göra dem värda besväret.
Så när chefen kommer in i det svåra vill han veta ID:n för alla sportbilar han har .
Detta är en enkel sammanfogning med två bord. Vi har en tabell som identifierar modellen och tabellen med tillgängligt lager i. Som du kan se, data i model
kolumnen för cars
tabellen relaterar till models
kolumnen för cars
bord vi har. Nu vet vi att modelltabellen har ett ID på 1
för Sports
så låt oss skriva anslutningen.
select
ID,
model
from
cars
join models
on model=ID
Så den här frågan ser bra ut? Vi har identifierat de två tabellerna och innehåller den information vi behöver och använder en koppling som korrekt identifierar vilka kolumner vi ska gå med i.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
Åh nej! Ett fel i vår första fråga! Ja, och det är ett plommon. Du förstår, frågan har verkligen fått rätt kolumner, men några av dem finns i båda tabellerna, så databasen blir förvirrad om vilken kolumn vi egentligen menar och var. Det finns två lösningar för att lösa detta. Den första är trevlig och enkel, vi kan använda tableName.columnName
för att berätta för databasen exakt vad vi menar, så här:
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 andra används förmodligen oftare och kallas för tabellaliasing. Tabellerna i det här exemplet har fina och korta enkla namn, men skriver ut något som KPI_DAILY_SALES_BY_DEPARTMENT
skulle förmodligen bli gammal snabbt, så ett enkelt sätt är att smeknamnet tabellen så här:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
Nu tillbaka till begäran. Som du kan se har vi den information vi behöver, men vi har också information som inte efterfrågades, så vi måste inkludera en var-klausul i uttalandet för att bara få de sportbilar som efterfrågades. Eftersom jag föredrar tabellaliasmetoden snarare än att använda tabellnamnen om och om igen, kommer jag att hålla fast vid den från och med denna punkt.
Det är klart att vi måste lägga till en where-klausul i vår fråga. Vi kan identifiera sportbilar antingen med ID=1
eller model='Sports'
. Eftersom ID:t är indexerat och primärnyckeln (och det råkar vara mindre att skriva), kan vi använda det i vår fråga.
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 är glad. Naturligtvis, när han är chef och aldrig är nöjd med det han bad om, tittar han på informationen och säger sedan Jag vill också ha färgerna .
Okej, så vi har redan skrivit en stor del av vår fråga, men vi måste använda en tredje tabell som är färger. Nu, vår huvudinformationstabell cars
lagrar bilens färg-ID och detta länkar tillbaka till kolumnen för färg-ID. Så, på samma sätt som originalet, kan vi gå med i en tredje tabell:
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)
Fan, även om tabellen var korrekt sammanfogad och de relaterade kolumnerna var länkade, glömde vi att ta in den faktiska informationen från den nya tabellen som vi just länkade.
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)
Okej, det är chefen från vår rygg för ett ögonblick. För att nu förklara en del av detta lite mer detaljerat. Som du kan se är from
klausul i vårt uttalande länkar till vår huvudtabell (jag använder ofta en tabell som innehåller information snarare än en uppslags- eller dimensionstabell. Frågan skulle fungera lika bra med alla tabeller omväxlade, men är mindre meningsfullt när vi kommer tillbaka till den här frågan att läsa den om några månader, så det är ofta bäst att försöka skriva en fråga som är trevlig och lätt att förstå - lägg upp den intuitivt, använd snygga indrag så att allt är så tydligt som det kan bli. fortsätt med att lära andra, försök att ingjuta dessa egenskaper i deras frågor - speciellt om du kommer att felsöka dem.
Det är fullt möjligt att fortsätta länka fler och fler tabeller på detta sätt.
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
Medan jag glömde att inkludera en tabell där vi kanske vill slå samman mer än en kolumn i join
uttalande, här är ett exempel. Om models
tabellen hade varumärkesspecifika modeller och hade därför också en kolumn som heter brand
som länkade tillbaka till brands
tabellen på ID
fältet kan det göras så här:
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, frågan ovan länkar inte bara de sammanfogade tabellerna till de viktigaste cars
tabell, men anger också kopplingar mellan de redan sammanfogade tabellerna. Om detta inte gjordes kallas resultatet en kartesisk join - vilket är dba speak for bad. En kartesisk koppling är en där rader returneras eftersom informationen inte talar om för databasen hur resultaten ska begränsas, så frågan returnerar alla raderna som passar kriterierna.
Så, för att ge ett exempel på en kartesisk koppling, låt oss köra följande fråga:
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)
Herregud, det är fult. Men när det gäller databasen är det exakt vad som efterfrågades. I frågan bad vi om ID
från cars
och model
från models
. Men eftersom vi inte specificerade hur för att gå med i tabellerna har databasen matchat alla rad från den första tabellen med varje rad från den andra tabellen.
Okej, så chefen är tillbaka och han vill ha mer information igen. Jag vill ha samma lista, men även inkludera 4WD i den .
Detta ger oss dock en bra ursäkt att titta på två olika sätt att åstadkomma detta. Vi skulle kunna lägga till ytterligare ett villkor till where-satsen så här:
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
Även om ovanstående kommer att fungera utmärkt, låt oss se på det annorlunda, det här är en bra ursäkt för att visa hur en union
frågan kommer att fungera.
Vi vet att följande kommer att returnera alla sportbilar:
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
Och följande skulle returnera alla 4WD:
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å genom att lägga till en union all
klausul mellan dem, kommer resultaten av den andra frågan att läggas till resultaten av den första frågan.
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 returneras resultatet av den första frågan först, följt av resultatet av den andra frågan.
I det här exemplet hade det naturligtvis varit mycket lättare att helt enkelt använda den första frågan, men union
frågor kan vara bra för specifika fall. De är ett utmärkt sätt att returnera specifika resultat från tabeller från tabeller som inte är lätta att sammanfoga - eller för den delen helt orelaterade tabeller. Det finns dock några regler att följa.
- Kolumntyperna från den första frågan måste matcha kolumntyperna från alla andra frågor nedan.
- Namnen på kolumnerna från den första frågan kommer att användas för att identifiera hela uppsättningen resultat.
- Antalet kolumner i varje fråga måste vara detsamma.
Nu kanske du undrar vad den
skillnaden är mellan att använda union
och union all
. En union
fråga kommer att ta bort dubbletter, medan en union all
ska inte. Detta betyder att det finns en liten prestandaträff när du använder union
över union all
men resultatet kan vara värt det - jag kommer dock inte att spekulera i sånt här.
På denna anteckning kan det vara värt att notera några ytterligare anteckningar här.
- Om vi vill beställa resultaten kan vi använda en
order by
men du kan inte använda aliaset längre. I frågan ovan, lägg till enorder by a.ID
skulle resultera i ett fel - vad gäller resultaten kallas kolumnenID
istället föra.ID
- även om samma alias har använts i båda frågorna. - Vi kan bara ha en
order by
påstående, och det måste vara som det sista påståendet.
För nästa exempel lägger jag till några extra rader i våra tabeller.
Jag har lagt till Holden
till märkestabellen. Jag har också lagt till en rad i cars
som har color
värdet 12
- som inte har någon referens i färgtabellen.
Okej, chefen är tillbaka igen, skällande förfrågningar ut - *Jag vill ha en räkning av varje märke vi har och antalet bilar i det!` - Typiskt, vi kommer bara till en intressant del av vår diskussion och chefen vill ha mer arbete .
Okej, så det första vi behöver göra är att få en komplett lista över möjliga varumärken.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
Nu, när vi ansluter detta till vår biltabell får vi följande 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)
Vilket naturligtvis är ett problem - vi ser inget omnämnande av den vackra Holden
varumärke jag lagt till.
Detta beror på att en koppling letar efter matchande rader i båda tabeller. Eftersom det inte finns några data i bilar som är av typen Holden
den lämnas inte tillbaka. Det är här vi kan använda en outer
Ansluta sig. Detta kommer att returnera alla resultaten från en tabell oavsett om de matchas i den andra tabellen eller inte:
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 när vi har det kan vi lägga till en härlig sammanställningsfunktion för att få en räkning och få chefen från oss för ett ögonblick.
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)
Och med det, bort chefen skulker.
För att förklara detta mer i detalj, kan yttre kopplingar vara till left
eller right
typ. Vänster eller Höger definierar vilken tabell som är fullständigt ingår. En left outer join
kommer att inkludera alla rader från tabellen till vänster, medan (du gissade rätt) en right outer join
tar med alla resultat från tabellen till höger till resultaten.
Vissa databaser tillåter en full outer join
vilket ger resultat (oavsett om det matchas eller inte) från båda tabeller, men detta stöds inte i alla databaser.
Nu, jag antar förmodligen vid denna tidpunkt, undrar du om du kan slå samman sammanfogningstyper i en fråga eller inte - och svaret är 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å varför är det inte det resultat som förväntades? Det beror på att även om vi har valt den yttre sammanfogningen från bilar till märken, så specificerades den inte i sammanfogningen till färger - så den specifika sammanfogningen kommer bara att ge resultat som matchar i båda tabellerna.
Här är frågan som skulle fungera för att få de resultat vi förväntade oss:
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 två yttre kopplingar i frågan och resultaten kommer fram som förväntat.
Nu, vad sägs om de andra typerna av anslutningar du frågar? Hur är det med Intersections?
Tja, alla databaser stöder inte intersection
men i stort sett alla databaser tillåter dig att skapa en skärningspunkt genom en join (eller åtminstone en välstrukturerad where-sats).
En korsning är en typ av sammanfogning som något liknar en union
som beskrivits ovan - men skillnaden är att det endast returnerar rader med data som är identiska (och jag menar identiska) mellan de olika individuella frågorna som förbundet anslutit sig till. Endast rader som är identiska i alla avseenden kommer att returneras.
Ett enkelt exempel skulle vara som sådant:
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
Medan en vanlig union
query skulle returnera alla rader i tabellen (den första frågan returnerar något över ID>2
och den andra allt som har ID<4
) vilket skulle resultera i en fullständig uppsättning, skulle en skärningsfråga endast returnera raden som matchar id=3
eftersom den uppfyller båda kriterierna.
Nu, om din databas inte stöder en intersect
fråga, kan ovanstående enkelt utföras med följande fråga:
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)
Om du vill utföra en korsning över två olika tabeller med en databas som inte i sig stöder en korsningsfråga, måste du skapa en sammanfogning på varje kolumn av tabellerna.