MS SQL v příkladech: Poddotazy v příkladech
Minule jsme si vyzkoušeli dotazy přes více tabulek, dnes se zaměříme na poddotazy. Výsledek SQL dotazu totiž může velmi jednoduše sloužit jako zdroj pro další SELECT. Buďte však opatrní, protože se jedná o časově náročné operace a poddotazy jsou obecně velmi pomalé.
Opět jsem se příklady snažil seřadit dle jejich složitosti.
Příklad 1: Vypsání článků, jejichž autorem je uživatel s přezdívkou David.
SELECT Titulek, Perex, Obsah FROM Clanek WHERE AutorID = ( SELECT UzivatelID FROM Uzivatel WHERE Nick = 'David' );
Příklad 2: Zjištění průměrného počtu článků na uživatele.
SELECT AVG(X) FROM ( SELECT COUNT(*) X FROM Clanek GROUP BY (AutorID) ) a;
Příklad 3: Zjistit průměrný výsledek ze zadaného testu.
SELECT AVG(Skore) Vysledek FROM ( SELECT Skore FROM VysledekTestu WHERE (TestID = 1) ) a;
Příklad 4: Zjistit průměrný výsledek ze všech testů na portálu.
SELECT AVG(Skore) Vysledek FROM ( SELECT Skore FROM VysledekTestu ) a;
Příklad 5: Jaký je nejlepší průměrný výsledek v testech.
SELECT MAX(X) Vysledek FROM ( SELECT AVG(Skore) X FROM ( SELECT Skore, UzivatelID FROM VysledekTestu ) a GROUP BY (UzivatelID) ) b;
Příklad 6: Vypsání článků, které nepatří do žádné sekce.
SELECT c.ClanekID, c.Titulek FROM Clanek c WHERE (SELECT COUNT(*) FROM ClanekSekce WHERE (ClanekSekce.ClanekID = c.ClanekID)) = 0;
Příklad 7: Vybrat uživatele, kteří mají nejlepší výsledek z testu s určitým ID (díky poddotazu můžeme vybrat více hodnot).
SELECT Nick, Skore FROM VysledekTestu, Uzivatel WHERE (VysledekTestu.Skore=( SELECT MAX(Skore) FROM VysledekTestu WHERE TestID = 1)) AND (TestID = 1) AND (VysledekTestu.UzivatelID = Uzivatel.UzivatelID);
Příklad 8: Vypsání komentářů, které jsou novější, než všechny komentáře autora s danou přezdívkou (slouží uživatelům k zobrazení komentářů, které ještě nečetli od své poslední aktivity na webu, tedy od napsání svých komentářů).
SELECT Obsah, Datum FROM Komentar WHERE Datum > ALL ( SELECT Datum FROM Komentar JOIN Uzivatel ON (Uzivatel.UzivatelID = Komentar.UzivatelID) WHERE (Uzivatel.Nick = 'Denny') ) ORDER BY Datum DESC;
Příklad 9: Který uživatel napsal nejvyšší počet článků.
SELECT TOP 1 U.Nick, ( SELECT COUNT(*) FROM Clanek WHERE (Clanek.AutorID = U.UzivatelID) ) CNT FROM Uzivatel U ORDER BY CNT DESC;
Příklad 10: Který uživatel má nejlepší průměrný výsledek v testech.
SELECT TOP 1 U.Nick, ( SELECT AVG(Skore) FROM ( SELECT Skore FROM VysledekTestu WHERE UzivatelID = U.UzivatelID ) X ) Vysledek FROM Uzivatel U ORDER BY Vysledek DESC;
Pohledy
Příklad 11: Rozhodli jsme se uložit si příkaz na vypsání nejnovějšího článku do pohledu.
CREATE VIEW NejnovejsiClanek AS SELECT TOP 1 c.Perex, c.PrettyURL, c.Titulek, c.Publikovano, u.Nick FROM Clanek c, Uzivatel u WHERE (u.UzivatelID = c.AutorID) ORDER BY c.Publikovano DESC;
Následně budeme volat jen zkráceně:
SELECT * FROM NejnovejsiClanek
Další dotazy
Následující dotazy jsem nechával na konec, protože mění obsah nebo strukturu databáze a mohly by zasahovat do předchozích příkladů. Udělejme si je tedy nyní:
Příklad 12: Občas je třeba vymazat nevhodný komentář.
DELETE FROM Komentar WHERE KomentarID = 5;
Příklad 13: Ukázalo se jako potřebné přidat k článkům hodnocení (podobné, jako like na facebooku).
ALTER TABLE Clanek ADD Palcu int;
Příklad 14: Pro obnovu tabulky komentáře ze zálohy (kvůli útoku spambotů) se musí tabulka nejprve vymazat, proto byl dodán následující dotaz.
DROP TABLE Komentar;
Příště si řekneme něco o optimalizaci MS SQL databáze.