Část 1 – Spojení a spojení
Tato odpověď zahrnuje:
- Část 1
- Spojení dvou nebo více tabulek pomocí vnitřního spojení (viz záznam ve wikipedii pro další informace)
- Jak používat sjednocovací dotaz
- Levé a pravé vnější spojení (tato odpověď stackOverflow je vynikající pro popis typů spojení)
- Protínají se dotazy (a jak je reprodukovat, pokud je vaše databáze nepodporuje) – toto je funkce SQL-Serveru (viz informace ) a část důvod, proč jsem to celé napsal na prvním místě.
- Část 2
- Poddotazy – co to jsou, kde je lze použít a na co si dát pozor
- Cartesian se připojuje k AKA – Ach, ta bída!
Existuje řada způsobů, jak načíst data z více tabulek v databázi. V této odpovědi budu používat syntaxi spojení ANSI-92. To se může lišit od řady jiných výukových programů, které používají starší syntaxi ANSI-89 (a pokud jste zvyklí na 89, může se vám zdát mnohem méně intuitivní – ale mohu říci jen to zkusit), protože je hodně snáze pochopitelné, když se dotazy začnou stávat složitějšími. Proč to používat? Dochází k nárůstu výkonu? krátká odpověď není, ale je snadněji se čte, jakmile si na to zvyknete. Pomocí této syntaxe je snazší číst dotazy napsané jinými lidmi.
Budu také používat koncept malého caryardu, který má databázi pro sledování toho, jaká auta má k dispozici. Majitel si vás najal jako svého IT počítačového chlápka a očekává, že mu budete moci okamžitě předat data, o která žádá.
Vytvořil jsem několik vyhledávacích tabulek, které budou použity v konečné tabulce. To nám dá rozumný model, ze kterého můžeme pracovat. Pro začátek budu spouštět své dotazy na ukázkové databázi, která má následující strukturu. Pokusím se myslet na běžné chyby, které se dělají, když začínáte, a vysvětlím, co je na nich špatně – a samozřejmě také ukážu, jak je napravit.
První tabulka je pouze seznam barev, abychom věděli, jaké barvy máme na dvoře.
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)
Tabulka značek identifikuje různé značky vozů, které by se na vozovně mohly prodávat.
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)
Tabulka modelů bude pokrývat různé typy aut, bude jednodušší použít různé typy aut spíše než skutečné modely aut.
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)
A nakonec, abychom svázali všechny tyto další stoly, stůl, který vše spojuje dohromady. Pole ID je ve skutečnosti jedinečné číslo šarže používané k identifikaci automobilů.
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)
To nám poskytne dostatek dat (doufám), že pokryjeme níže uvedené příklady různých typů spojení a také dostatek dat, aby se vyplatily.
Šéf se tedy chce dozvědět ID všech sportovních vozů, které má .
Jedná se o jednoduché spojení dvou stolů. Máme tabulku, která identifikuje model a tabulku s dostupnými zásobami v něm. Jak můžete vidět, data v model
sloupec cars
tabulka se vztahuje k models
sloupec cars
stůl máme. Nyní víme, že tabulka modelů má ID 1
pro Sports
tak pojďme napsat join.
select
ID,
model
from
cars
join models
on model=ID
Takže tento dotaz vypadá dobře? Identifikovali jsme dvě tabulky a obsahují informace, které potřebujeme, a používáme spojení, které správně identifikuje, ke kterým sloupcům se má připojit.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
Ach ne! Chyba v našem prvním dotazu! Ano, a je to švestka. Vidíte, dotaz má skutečně správné sloupce, ale některé z nich existují v obou tabulkách, takže databáze je zmatená, jaký skutečný sloupec máme na mysli a kde. Existují dvě řešení, jak to vyřešit. První je pěkný a jednoduchý, můžeme použít tableName.columnName
sdělit databázi přesně, co máme na mysli, takto:
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)
Ten druhý se pravděpodobně používá častěji a nazývá se aliasing tabulky. Tabulky v tomto příkladu mají pěkné a krátké jednoduché názvy, ale zadejte něco jako KPI_DAILY_SALES_BY_DEPARTMENT
pravděpodobně rychle zestárne, takže jednoduchým způsobem je pojmenovat tabulku takto:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
Nyní zpět k žádosti. Jak vidíte, máme informace, které potřebujeme, ale máme také informace, o které jsme nepožádali, takže musíme do prohlášení zahrnout klauzuli where, abychom dostali sportovní vozy pouze tak, jak bylo požadováno. Vzhledem k tomu, že preferuji metodu aliasů tabulek před používáním názvů tabulek stále dokola, budu se jí od tohoto okamžiku dále držet.
Je jasné, že do našeho dotazu musíme přidat klauzuli where. Sportovní vozy můžeme identifikovat buď podle ID=1
nebo model='Sports'
. Protože je ID indexováno a primární klíč (a shodou okolností se méně píše), pojďme to použít v našem dotazu.
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! Šéf je šťastný. Samozřejmě, protože je šéf a nikdy není spokojený s tím, o co požádal, podívá se na informace a pak řekne Chci také barvy .
Dobrá, takže velkou část našeho dotazu již máme napsanou, ale musíme použít třetí tabulku, kterou jsou barvy. Nyní naše hlavní informační tabulka cars
ukládá ID barvy auta a to se vrací zpět do sloupce ID barev. Takže podobným způsobem jako originál můžeme připojit třetí tabulku:
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)
Sakra, ačkoli byla tabulka správně spojena a související sloupce byly propojeny, zapomněli jsme načíst skutečné informace z nové tabulky, kterou jsme právě propojili.
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)
Dobře, to je na chvíli šéf pryč z našich zad. Nyní, abychom některé z nich vysvětlili trochu podrobněji. Jak můžete vidět, from
klauzule v našem prohlášení propojuje naši hlavní tabulku (často používám tabulku, která obsahuje informace spíše než vyhledávací nebo dimenzní tabulku. Dotaz by fungoval stejně dobře se všemi přepnutými tabulkami, ale když se vrátíme k tomuto dotazu, dává to menší smysl přečíst za několik měsíců, takže je často nejlepší pokusit se napsat dotaz, který bude pěkný a srozumitelný - rozložte jej intuitivně, použijte pěkné odsazení, aby bylo vše tak jasné, jak jen může být. pokračujte v učení ostatních, snažte se vštípit tyto vlastnosti do jejich dotazů – zvláště pokud je budete řešit.
Tímto způsobem je zcela možné propojovat další a další tabulky.
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
I když jsem zapomněl zahrnout tabulku, kde bychom mohli chtít spojit více než jeden sloupec v join
prohlášení, zde je příklad. Pokud models
tabulka měla modely specifické pro značku, a proto měla také sloupec nazvaný brand
které odkazovaly zpět na brands
tabulka na ID
pole, mohlo by to být provedeno takto:
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
Vidíte, že výše uvedený dotaz nejen propojuje spojené tabulky s hlavními cars
tabulka, ale také určuje spojení mezi již spojenými tabulkami. Pokud to nebylo provedeno, výsledek se nazývá kartézské spojení - což je dba špatně. Kartézské spojení je takové, kde jsou vráceny řádky, protože informace neříkají databázi, jak omezit výsledky, takže dotaz vrátí vše řádky, které splňují kritéria.
Abychom uvedli příklad kartézského spojení, spusťte následující dotaz:
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)
Dobrý bože, to je ošklivé. Co se však databáze týče, je to přesně o co bylo požádáno. V dotazu jsme požadovali ID
z cars
a model
z models
. Protože jsme však nespecifikovali jak pro připojení k tabulkám se databáze shodovala každý řádek z první tabulky s každým řádek z druhé tabulky.
Dobře, takže šéf je zpět a chce znovu více informací. Chci stejný seznam, ale také do něj zahrnout 4WD .
To nám však dává skvělou výmluvu, abychom se podívali na dva různé způsoby, jak toho dosáhnout. Do klauzule where bychom mohli přidat další podmínku, jako je tato:
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
I když výše uvedené bude fungovat naprosto dobře, podívejme se na to jinak, je to skvělá výmluva, jak ukázat, jak union
dotaz bude fungovat.
Víme, že následující vrátí všechny sportovní vozy:
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
A následující by vrátila všechna 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
Takže přidáním union all
klauzule mezi nimi, výsledky druhého dotazu budou připojeny k výsledkům prvního dotazu.
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)
Jak můžete vidět, výsledky prvního dotazu jsou vráceny jako první, následované výsledky druhého dotazu.
V tomto příkladu by bylo samozřejmě mnohem jednodušší jednoduše použít první dotaz, ale union
dotazy mohou být skvělé pro konkrétní případy. Jsou skvělým způsobem, jak vrátit konkrétní výsledky z tabulek z tabulek, které se nedají snadno spojit – nebo když na to přijde úplně nesouvisející tabulky. Je však třeba dodržovat několik pravidel.
- Typy sloupců z prvního dotazu se musí shodovat s typy sloupců z každého dalšího dotazu níže.
- K identifikaci celé sady výsledků budou použity názvy sloupců z prvního dotazu.
- Počet sloupců v každém dotazu musí být stejný.
Možná vás přemýšlí, co
rozdíl je mezi použitím union
a union all
. union
dotaz odstraní duplikáty, zatímco union all
nebude. To znamená, že při použití union
dochází k malému snížení výkonu přes union all
ale výsledky mohou stát za to – o něčem takovém v tomto nebudu spekulovat.
K této poznámce by zde možná stálo za zmínku několik dalších poznámek.
- Pokud bychom chtěli výsledky seřadit, můžeme použít
order by
ale alias už nemůžete používat. Ve výše uvedeném dotazu přidejteorder by a.ID
by vedlo k chybě - pokud jde o výsledky, sloupec se nazýváID
spíše neža.ID
- i když byl v obou dotazech použit stejný alias. - Můžeme mít pouze jednu
order by
příkaz a musí to být jako poslední příkaz.
Pro další příklady přidávám do našich tabulek několik řádků navíc.
Přidal jsem Holden
do tabulky značek. Také jsem přidal řádek do cars
který má color
hodnota 12
- který nemá žádný odkaz v tabulce barev.
Dobře, šéf je zase zpátky, štěkot žádá - *Chci počet každé značky, kterou vezeme, a počet aut v ní!` - Typické, že se právě dostaneme do zajímavé části naší diskuse a šéf chce více práce .
Rightyo, takže první věc, kterou musíme udělat, je získat kompletní seznam možných značek.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
Nyní, když to připojíme k naší tabulce vozů, dostaneme následující výsledek:
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)
Což je samozřejmě problém – nevidíme žádnou zmínku o krásném Holden
značka, kterou jsem přidal.
Je to proto, že spojení hledá odpovídající řádky v obě tabulky. Protože v autech nejsou žádná data typu Holden
není to vráceno. Zde můžeme použít outer
připojit. Tím vrátíte vše výsledky z jedné tabulky bez ohledu na to, zda se shodují v druhé tabulce:
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)
Teď, když to máme, můžeme přidat nádhernou agregační funkci, která spočítá a na chvíli dostane šéfa ze zad.
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)
A s tím pryč šéfové skuvky.
Nyní, abychom to vysvětlili podrobněji, vnější spojení mohou být left
nebo right
typ. Vlevo nebo vpravo určuje, která tabulka je úplná zahrnuta. left outer join
bude zahrnovat všechny řádky z tabulky vlevo, zatímco (uhodli jste) right outer join
přenese do výsledků všechny výsledky z tabulky vpravo.
Některé databáze umožňují full outer join
který vrátí výsledky (ať už se shodují, nebo ne) z obou tabulky, ale to není podporováno ve všech databázích.
Pravděpodobně si v tuto chvíli říkáte, zda můžete sloučit typy spojení v dotazu nebo ne – a odpověď je ano, rozhodně můžete.
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)
Proč to tedy nejsou výsledky, které se očekávaly? Je to proto, že ačkoli jsme vybrali vnější spojení z aut na značky, nebylo to specifikováno ve spojení s barvami - takže toto konkrétní spojení přinese pouze výsledky, které se shodují v obou tabulkách.
Zde je dotaz, který by fungoval k získání výsledků, které jsme očekávali:
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)
Jak vidíme, v dotazu máme dvě vnější spojení a výsledky přicházejí podle očekávání.
A co ty další typy spojení, na které se ptáš? A co křižovatky?
Ne všechny databáze podporují intersection
ale téměř všechny databáze vám umožní vytvořit průnik prostřednictvím spojení (nebo alespoň dobře strukturovaného příkazu where).
Průsečík je typ spojení do jisté míry podobný union
jak je popsáno výše – ale rozdíl je v tom, že pouze vrátí řádky dat, které jsou identické (a myslím identické) mezi různými jednotlivými dotazy spojenými sjednocením. Budou vráceny pouze řádky, které jsou ve všech ohledech totožné.
Jednoduchý příklad by byl takový:
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
Zatímco normální union
dotaz by vrátil všechny řádky tabulky (první dotaz vrátil něco přes ID>2
a druhý cokoli s ID<4
), což by vedlo k úplné sadě, protínající dotaz by vrátil pouze řádek odpovídající id=3
protože splňuje obě kritéria.
Nyní, pokud vaše databáze nepodporuje intersect
výše uvedené lze snadno vyřešit pomocí následujícího dotazu:
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)
Pokud chcete provést průnik mezi dvěma různými tabulkami pomocí databáze, která ve své podstatě nepodporuje průnikový dotaz, budete muset vytvořit spojení pro každý sloupec z tabulek.