MS SQL v príkladoch: Poddotazy v príkladoch
Minule sme si vyskúšali otázky cez viacero tabuliek, dnes sa zameriame na poddotazy. Výsledok SQL dotazu totiž môže veľmi jednoducho slúžiť ako zdroj pre ďalší SELECT. Buďte však opatrní, pretože ide o časovo náročné operácie a poddotazy sú vo všeobecnosti veľmi pomalé.
Opäť som sa príklady snažil zoradiť podľa ich zložitosti.
Príklad 1: Vypísanie článkov, ktorých autorom je užívateľ s prezývkou David.
SELECT Titulek, Perex, Obsah FROM Clanek WHERE AutorID = ( SELECT UzivatelID FROM Uzivatel WHERE Nick = 'David' );
Príklad 2: Zistenie priemerného počtu článkov na užívateľa.
SELECT AVG(X) FROM ( SELECT COUNT(*) X FROM Clanek GROUP BY (AutorID) ) a;
Príklad 3: Zistiť priemerný výsledok zo zadaného testu.
SELECT AVG(Skore) Vysledek FROM ( SELECT Skore FROM VysledekTestu WHERE (TestID = 1) ) a;
Príklad 4: Zistiť priemerný výsledok zo všetkých testov na portáli.
SELECT AVG(Skore) Vysledek FROM ( SELECT Skore FROM VysledekTestu ) a;
Príklad 5: Aký je najlepší priemerný výsledok v testoch.
SELECT MAX(X) Vysledek FROM ( SELECT AVG(Skore) X FROM ( SELECT Skore, UzivatelID FROM VysledekTestu ) a GROUP BY (UzivatelID) ) b;
Príklad 6: Vypísanie článkov, ktoré nepatria do žiadnej sekcie.
SELECT c.ClanekID, c.Titulek FROM Clanek c WHERE (SELECT COUNT(*) FROM ClanekSekce WHERE (ClanekSekce.ClanekID = c.ClanekID)) = 0;
Príklad 7: Vybrať užívateľov, ktorí majú najlepší výsledok z testu s určitým ID (vďaka poddotazu môžeme vybrať viac hodnôt).
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);
Príklad 8: Vypísanie komentárov, ktoré sú novšie, než všetky komentáre autora s danou prezývkou (slúžia užívateľom na zobrazenie komentárov, ktoré ešte nečítali od svojej poslednej aktivity na webe, teda od napísania svojich komentárov).
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;
Príklad 9: Ktorý používateľ napísal najvyšší počet článkov.
SELECT TOP 1 U.Nick, ( SELECT COUNT(*) FROM Clanek WHERE (Clanek.AutorID = U.UzivatelID) ) CNT FROM Uzivatel U ORDER BY CNT DESC;
Príklad 10: Ktorý používateľ má najlepší priemerný výsledok v testoch.
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;
Pohľady
Príklad 11: Rozhodli sme sa uložiť si príkaz na vypísanie najnovšieho článku do pohľadu.
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ásledne budeme volať len skrátene:
SELECT * FROM NejnovejsiClanek
Ďalšie otázky
Nasledujúce otázky som nechával na koniec, pretože mení obsah alebo štruktúru databázy a mohli by zasahovať do predchádzajúcich príkladov. Urobme si ich teda teraz:
Príklad 12: Občas je potrebné vymazať nevhodný komentár.
DELETE FROM Komentar WHERE KomentarID = 5;
Príklad 13: Ukázalo sa ako potrebné pridať k článkom hodnotenia (podobné, ako like na facebooku).
ALTER TABLE Clanek ADD Palcu int;
Príklad 14: Pre obnovu tabuľky komentára zo zálohy (kvôli útoku spambotov) sa musí tabuľka najprv vymazať, preto bol dodaný nasledujúci dotaz.
DROP TABLE Komentar;
Nabudúce si povieme niečo o optimalizácii MS SQL databázy.