VyÜlo: 7.12.2000 Rubrika:
ASP - SQL
SQL: Spojenφ dvou tabulek volnou vazbou
Chcete se nauΦit propojit nezßvisle na sob∞ dv∞ tabulky? Zßvislost jednΘ bu≥ky na jinΘ, kterß je v jinΘ tabulce? Äßdn² problΘm. Podrobn² nßvod naleznete v Φlßnku...
Rßd bych se cht∞l zam∞°it na mo₧nost spojenφ vφce tabulek na tzv. volnΘ spojenφ.
VolnΘ spojenφ se dß jednoduÜe popsat nßsledovn∞: spojujeme
dv∞ tabulky p°es vazebnφ sloupec, p°iΦem₧ nemusφ existovat zßznam v "druhΘ" tabulce.
╪eÜenφ tΘto situace m∞ zaujalo, jeliko₧ tohoto spojenφ b∞₧n∞ pou₧φvßm v databßzi
ORACLE a pot°eboval jsem toto provΘst i v databßzi MS ACCESS a chvφli mi trvalo,
ne₧ jsem p°iÜel na °eÜenφ. P°φklad uvedu, proto₧e databßze MS ACCESS je Φasto
jedinß podporovanß databßze spoleΦn∞ s mo₧nostφ generovßnφ strßnek pomocφ ASP na hostingov²ch serverech.
Nap°.: chceme spojit tabulku s daty o rodiΦφch (zam∞stnancφch) a d∞tech zam∞stnanc∙. Je jasnΘ, ₧e ne vÜichni zam∞stnanci musφ mφt d∞ti. VÜe uvedu na p°φkladu pro MS ACCESS a ORACLE, na kter²ch bude p∞kn∞ vid∞t rozdφl.
Nadefinujeme si dv∞ tabulky:
ZAMESTNANCI: |
ID_ZAM | Number |
JMENO_ZAM | Char(30) |
PRIJMENI_ZAM | Char(30) |
TEL_ZAM | Char(15) |
PLAT | Number |
|
DETI_ZAM |
ID_DITETE | Number |
ID_ZAM | Number |
JMENO_DITETE | Char(30) |
PRIJMENI_DITETE | Char(30) |
Tabulky jsem nadefinoval jen pro nßzorn² p°φklad, proto si ka₧d² m∙₧e upravit definici
podle svΘho. Ji₧ z definic tabulek je jasnΘ, ₧e vazebnφm sloupcem je ID_ZAM.
Tato hodnota v tabulce ZAMESTNANCI musφ existovat a v tabulce DETI_ZAM nemusφ. OpaΦn² p°φpad by nem∞l nastat, jeliko₧ bychom v datech nem∞li mφt d∞ti
zam∞stnanc∙, kte°φ u nßs neexistujφ.
Zde uvedu v²pisy jednotliv²ch tabulek. Na nich pak bude lΘpe vid∞t v²sledek.
ID_ZAM |
JMENO_ZAM |
PRIJMENI_ZAM |
TEL_ZAM |
PLAT |
1 |
FratiÜek |
Novßk |
0603 111 111 |
10000 |
2 |
Tonda |
Novßk |
0604 222 222 |
8000 |
3 |
Tereza |
Smolφkovß |
0605 333 333 |
9000 |
4 |
Adam |
╚ech |
0606 444 444 |
15000 |
ID_DITETE |
ID_ZAM |
JMENO_DITETE |
PRIJMENI_DITETE |
1 |
1 |
AdΘla |
Novßkovß |
2 |
1 |
Honza |
Novßk |
3 |
3 |
Roman |
Smolφk |
4 |
3 |
Ji°φ |
Smolφk |
5 |
3 |
Petra |
Smolφkovß |
P°edpoklßdejme, ₧e pot°ebujeme vybrat z t∞chto dvou tabulek jmΘno a p°φjmenφ
zam∞stnance a jeho d∞tφ. Pokud bychom pou₧ili pevnΘ spojenφ t∞chto tabulek, dojde k tomu,
₧e se vyberou pouze zam∞stnanci, kte°φ majφ alespo≥ jedno dφt∞. P°φklad je mo₧no vyu₧φt
pro v²poΦet snφ₧enφ zßkladu platu (mo₧nΘ pouze u jednoho z rodiΦ∙).
Nejd°φve si ukß₧eme pevnΘ spojenφ:
ORACLE:
Select a.JMENO_ZAM, a.PRIJMENI_ZAM, b.JMENO_DITETE, b.PRIJMENI_DITETE
From ZAMESTNANCI a, DETI_ZAM b
Where a.ID_ZAM=b.ID_ZAM
MS ACCESS:
Select a.JMENO_ZAM, a.PRIJMENI_ZAM, b.JMENO_DITETE, b.PRIJMENI_DITETE
From ZAMESTNANCI a, DETI_ZAM b
Where a.ID_ZAM=b.ID_ZAM
Jak² je rozdφl mezi t∞mito v²b∞ry? Äßdn². V tomto p°φpad∞ se jednß o naprost²
standart SQL a nenφ v niΦem problΘm. Ne v₧dy se vÜak pevnΘ spojenφ tabulek hodφ.
P°φklad takovΘho v²pisu(v²stupu):
JMENO_ZAM |
PRIJMENI_ZAM |
JMENO_DITETE |
PRIJMENI_DITETE |
FratiÜek |
Novßk |
AdΘla |
Novßkovß |
FratiÜek |
Novßk |
Honza |
Novßk |
Tereza |
Smolφkovß |
Roman |
Smolφk |
Tereza |
Smolφkovß |
Ji°φ |
Smolφk |
Tereza |
Smolφkovß |
Petra |
Smolφkovß |
Z tohoto v²pisu je jasnΘ, ₧e nßm vypadli n∞kte°φ zam∞stnanci, co₧ nemusφ b²t v₧dy ₧ßdoucφ.
A nynφ ji₧ slibovanΘ volnΘ spojenφ dvou tabulek:
ORACLE:
Select a.JMENO_ZAM, a.PRIJMENI_ZAM, b.JMENO_DITETE, b.PRIJMENI_DITETE
From ZAMESTNANCI a, DETI_ZAM b
Where a.ID_ZAM=b.ID_ZAM(+)
MS ACCESS:
Select a.JMENO_ZAM, a.PRIJMENI_ZAM, b.JMENO_DITETE, b.PRIJMENI_DITETE From ZAMESTNANCI a
LEFT JOIN DETI_ZAM b ON a.ID_ZAM=b.ID_ZAM
Rozdφl v t∞chto zßpisech je znaΦn². V²sledek tohoto p°φkladu vidφte zde:
JMENO_ZAM |
PRIJMENI_ZAM |
JMENO_DITETE |
PRIJMENI_DITETE |
FratiÜek |
Novßk |
Honza |
Novßk |
FratiÜek |
Novßk |
AdΘla |
Novßkovß |
Tonda |
Novßk |
|
|
Tereza |
Smolφkovß |
Petra |
Smolφkovß |
Tereza |
Smolφkovß |
Ji°φ |
Smolφk |
Tereza |
Smolφkovß |
Roman |
Smolφk |
Adam |
╚ech |
|
|
Jak je vid∞t na tomto v²pisu tak zam∞stnanci, kte°φ nemajφ d∞ti nevypadli a namφsto
informacφ o jejich d∞tech se doplnily prßzdnΘ hodnoty.
JeÜt∞ v∞tÜφ rozdφl by nastal, pokud bychom cht∞li p°idat podmφnku
na n∞kterou z tabulek. To by vypadalo nßsledovn∞:
ORACLE:
Select a.JMENO_ZAM, a.PRIJMENI_ZAM, b.JMENO_DITETE, b.PRIJMENI_DITETE
From ZAMESTNANCI a, DETI_ZAM b
Where a.ID_ZAM=b.ID_ZAM(+)
And a.plat>8000
MS ACCESS:
Select a.JMENO_ZAM, a.PRIJMENI_ZAM, b.JMENO_DITETE, b.PRIJMENI_DITETE From ZAMESTNANCI a
LEFT JOIN DETI_ZAM b ON a.ID_ZAM=b.ID_ZAM
Where a.plat>8000
V²sledek tohoto v²b∞ru.
JMENO_ZAM |
PRIJMENI_ZAM |
JMENO_DITETE |
PRIJMENI_DITETE |
FratiÜek |
Novßk |
Honza |
Novßk |
FratiÜek |
Novßk |
AdΘla |
Novßkovß |
Tereza |
Smolφkovß |
Petra |
Smolφkovß |
Tereza |
Smolφkovß |
Ji°φ |
Smolφk |
Tereza |
Smolφkovß |
Roman |
Smolφk |
Adam |
╚ech |
|
|
Nu₧e, Tonda Novßk nßm vypadl, jeliko₧ mß plat pouze 8000 a ne v∞tÜφ.
A rozdφl v zßpisech v²b∞ru? Do zßpisu pro MS ACCESS jsme museli p°idat klauzuli
WHERE kde₧to v zßpisu pro ORACLE ji₧ tato klauzule byla. StaΦilo p°idat jen
jednu podmφnku.
VeÜkerΘ materißly zde uvedenΘ je mo₧nΘ stßhnout z tΘto adresy. Jednß se p°edevÜφm o kopletnφ zdrojovΘ k≤dy a ilustrativnφ databßzi.
DuÜan Porwol
mushing@mushing.cz
Souvisejφcφ Φlßnky
|