06.08.2014, Vladimír Klaus, navštíveno 3809x
Příkaz vrátí takové záznamy z prvního dotazu, které nejsou nalezeny ve druhém dotazu. Je to tedy vlastně odečítání, proto se v některých databázích tento příkaz nazývá MINUS. Tento příkaz MS Access ale nezná, a často se dá nahradit příkazem OUTER JOIN. Teď si asi říkáte – ale OUTER JOIN MS Access také nepodporuje, takže jak to tedy bude? Ještě jinak. Další variantou je totiž LEFT JOIN a ten už použít můžeme.
Jako základ vezmeme totéž, co je použito v části Příkaz INTERSECT. Mějme tedy dva základní dotazy – první vypíše zákazníky z Prahy a druhý zákazníky, kteří si objednali alespoň za 2000 Kč.
SELECT * FROM Zakaznici WHERE Mesto LIKE "Praha*"
SELECT * FROM Objednavky WHERE Castka >= 2000
Nyní nás zajímají zákazníci, kteří jsou sice z Prahy, ale objednali si za méně než 2000 Kč, tedy opravdu chci odečíst výsledek druhého dotazu od výsledku prvního dotazu.
Nejprve začneme běžným spojením pomocí INNER JOIN. Vlevo mám zákazníky z Prahy a vpravo pak připojím jejich objednávky, které jsou alespoň za 2000 Kč.
SELECT Zakaznici.ID, Zakaznici.Prijmeni, Zakaznici.Mesto,
Objednavky.Castka
FROM Zakaznici
INNER JOIN
(SELECT * FROM Objednavky WHERE Castka >= 2000) b
ON Zakaznici.ID = b.IdZakaznika
WHERE Zakaznici.Mesto LIKE "Praha*"
Když se nyní podíváte na první obrázek se všemi zákazníky z Prahy a tento, zjistíte, že se liší ve třech osobách. A o ty nám nyní jde. Dotaz musíme upravit tak, že změníme spojení na LEFT JOIN. To znamená, že vlevo budou i ty záznamy, kterým na pravé straně neodpovídá žádný záznam, díky nesplněné podmínce na částku. Jinak řečeno – takoví zákazníci, kteří sice mají nějaké objednávky, ale všechny jsou za méně než 2000, proto se k zákazníkovi připojí položky z objednávky, ale budou NULL.
SELECT Zakaznici.ID, Zakaznici.Prijmeni, Zakaznici.Mesto,
Objednavky.Castka, Objednavky.IdZakaznika
FROM Zakaznici
LEFT JOIN
(SELECT * FROM Objednavky WHERE Castka >= 2000) b
ON Zakaznici.ID = b.IdZakaznika
WHERE Zakaznici.Mesto LIKE "Praha*"
A to už jsme jen kousek od toho, abychom právě tyto prázdné položky využili. Do podmínky doplníme požadavek, aby byl IdZakaznika = NULL. Zároveň odstraníme Castku, protože přestává mít smysl ji vypisovat – bude NULL.
SELECT Zakaznici.ID, Zakaznici.Prijmeni, Zakaznici.Mesto
FROM Zakaznici
LEFT JOIN
(SELECT * FROM Objednavky WHERE Castka >= 2000) b
ON Zakaznici.ID = b.IdZakaznika
WHERE Zakaznici.Mesto LIKE "Praha*" AND b.IdZakaznika IS NULL
Možná se vám to zdá poněkud komplikované a napadne vás, že by to mělo jít řešit jednodušeji – pomocí podmínky Castka < 2000. Vyzkoušejte si to, není to možné.