V urΦit²ch okamihoch pri prßci s rozsiahlejÜou databßzou zistφme, ₧e s jednoduch²mi SQL dotazmi nevystaΦφme a potrebujeme zφska¥ naraz ·daje z viacer²ch tabuliek, ktorΘ s· navzßjom prepojenΘ urΦitou zßvislos¥ou.
Zoberme si prφpad, ₧e mßme jednu tabu╛ku v ktorej mßme zoznam naÜich pracovnφkov s osobn²mi Φφslami. Tßto tabu╛ka nßm poskytuje iba statick² poh╛ad na evidenciu pracovnφkov, ich poΦet a oznaΦenie jedineΦn²m identifikaΦn²m Φφslom. V druhej tabu╛ke (pracoviska) mßme zotriedenΘ a pomenovanΘ vÜetky pracoviskß na ktor²ch sa vyskytuj· naÜi zamestnanci. Na obΦerstvenie pamΣti uvßdzam cel² postup vytvorenia tabuliek:
create table pracovnici (pracovnik_id int, pracovnik_meno varchar(25))
create table pracoviska (pracovisko_id int, pracovnik_id int,
pracovisko_nazov varchar(25))
INSERT INTO pracovnici (pracovnik_id, pracovnik_meno) VALUES ('07', 'Jozef 3');
INSERT INTO pracovnici (pracovnik_id, pracovnik_meno) VALUES ('08', 'Peter 1');
INSERT INTO pracovnici (pracovnik_id, pracovnik_meno) VALUES ('02', 'Andrej 1');
INSERT INTO pracoviska (pracovisko_id, pracovnik_id, pracovisko_nazov)
VALUES ('11', '02', 'kniznica');
INSERT INTO pracoviska (pracovisko_id, pracovnik_id, pracovisko_nazov)
VALUES ('14', '02', 'uctaren');
INSERT INTO pracoviska (pracovisko_id, pracovnik_id, pracovisko_nazov)
VALUES ('19', '07', 'sklad');
mysql> select * from pracovnici;
+--------------+----------------+
| pracovnik_id | pracovnik_meno |
+--------------+----------------+
| 2 | Andrej 1 |
| 7 | Jozef 3 |
| 8 | Peter 1 |
+--------------+----------------+
3 rows in set (0.11 sec)
mysql> select * from pracoviska;
+---------------+--------------+------------------+
| pracovisko_id | pracovnik_id | pracovisko_nazov |
+---------------+--------------+------------------+
| 11 | 2 | kniznica |
| 14 | 2 | uctaren |
| 19 | 7 | sklad |
+---------------+--------------+------------------+
3 rows in set (0.06 sec)
Jednoduch²m selectom m⌠₧eme zisti¥ zoznam naÜich pracovnφkov z tabu╛ky (pracovnici) a napriklad zoznam pracovφsk z druhej tabu╛ky (pracoviska). ProblΘm nastßva v prφpade ₧e chceme zisti¥ meno pracovnφka ktor² pracuje naprφklad v sklade. Druhß tabu╛ka toti₧ neobsahuje ·daje o menßch pracovnφkov. RieÜenie by mohlo spoΦφva¥ v spojenφ naÜich dvoch tabuliek do jednej, ale ... no ale najsk⌠r si to ukß₧me:
pracovisko_id |
pracovisko_nazov |
pracovnik_id |
meno |
11 |
kniznica |
2 |
Andrej 1 |
14 |
uctaren |
2 |
Andrej 1 |
19 |
sklad |
8 |
Peter 1 |
Ke∩ mßme takto pekne spojenΘ dve tabu╛ky, nebude pre nßs problΘm vyselektova¥ pracovisko urΦitΘho pracovnφka:
SELECT pracovisko_nazov FROM (spojena_tabulka) WHERE pracovnik_meno='Andrej 1'
No dobre, ale Φo tak pou₧i¥ jeden prφkaz SELECT bez nutnosti spßjania naÜich dvoch tabuliek do jednej. Samozrejme aj to je mo₧nΘ a ukß₧eme si to na nßsledovnom prφklade:
mysql> SELECT pracovisko_nazov FROM pracovnici,pracoviska
-> WHERE (pracovnici.pracovnik_id=pracoviska.pracovnik_id)
-> AND (pracovnik_meno='Andrej 1');
A v²sledok by mohol vypada¥ asi takto:
+------------------+
| pracovisko_nazov |
+------------------+
| kniznica |
| uctaren |
+------------------+
2 rows in set (0.00 sec)
V tomto selecte sme spojili dve tabu╛ky prostrednφctvom spoloΦnΘho k╛·Φa za Φas¥ou WHERE a v ∩alÜej Φasti prφkazu sme odfiltrovali po₧adovanΘho pracovnika. Tento proces sa naz²va (v p⌠vodnomm tvare) "Cartesian-filter join", Φi₧e ho m⌠₧eme prirovna¥ ku KartezianskΘmu s·Φinu dvoch matφc (v naÜom prφpade tabuliek) kde je v²sledok vrßten² na zßklade ∩alÜφch kritΘriφ. Ale to u₧ zachßdzame trochu do Lineaßrnej algebry a teraz v lete to nie je urΦite prφjemnΘ ;-)
V bud·cej Φasti si povieme trochu hlbÜie o spßjanφ SQL tabuliek.