MySQL Φas¥ Üestnßsta - Spßjanie tabuliek v MySQL (I)
Dßtum: 11. July 2001
Vec: MySQL

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.



Tento Φlßnok je z Developer.sk
http://www.developer.sk/

URL pre tento prφspevok je:
http://www.developer.sk//article.php?sid=199