2. CVIČENÍ


Agregační funkce :

COUNT()vrací počet hodnot ve specifikovaném sloupci
SUM()vrací součet hodnot ve specifikovaném sloupci
AVG()vrací průměr z hodnot ve specifikovaném sloupci
MIN()vrací minimum z hodnot ve specifikovaném sloupci
MAX()vrací maximum z hodnot ve specifikovaném sloupci

Pozn.: agregační funkce nelze použít v klauzuli WHERE.

Výběr počtu záznamů :

SELECT COUNT(pisen) FROM cd;
V případě, že funkci COUNT() předáme jako parametr atribut jehož hodnota může být neurčena (NULL), vrací počet záznamů u kterých hodnota specifikovaného atributu není NULL :
SELECT COUNT(poznamka) FROM cd;
Chceme-li získat celkový počet všech záznamů bez ohledu na případné NULL hodnoty některých sloupců, použijeme jako parametr znak '*' :
SELECT COUNT(*) FROM cd;
Ve funkci COUNT() lze použít i klauzuli DISTINCT :
SELECT COUNT(DISTINCT interpret) FROM cd;
SELECT MIN(d_min), MAX(d_min), SUM(d_min), AVG(d_min) FROM cd;

Slučování vybraných záznamů do skupin :

SELECT  interpret,
        COUNT(stopa) AS pocet_stop,
        SUM(d_min * 60 + d_sec) AS delka
  FROM  cd
 GROUP  BY interpret
 ORDER  BY interpret;

Výběr skupin podle podmínky :

SELECT  interpret,
        COUNT(stopa) AS pocet_stop,
        SUM(d_min * 60 + d_sec) AS delka
  FROM  cd
 GROUP  BY interpret
HAVING  SUM(d_min * 60 + d_sec) > 300 AND COUNT(stopa) < 12
 ORDER  BY interpret;
Pozn.: v klauzuli HAVING nejdou použít nově definované názvy sloupců.

Vnořené dotazy :

Některé SQL příkazy mohou mít v sobě obsaženy další kompletní příkazy SELECT, kterým se říká vnořené dotazy. Ty se mohou vyskytovat v klauzulích WHERE a HAVING vnějšího příkazu SELECT. Vnořené dotazy se mohou vystkytovat i v příkazech INSERT, UPDATE a DELETE (viz. dále).

Nejdelší píseň :

SELECT  pisen, d_min
  FROM  cd
 WHERE  d_min = ( SELECT MAX(d_min) FROM cd );
Písně s nadprůměrnou délkou :
SELECT  pisen, d_min
  FROM  cd
 WHERE  d_min > ( SELECT AVG(d_min) FROM cd );
Pravidla, které je nutno dodržet při používání vnořených dotazů : Předchozí příklad s nejdelší písní lze přepsat také jako :
SELECT  pisen, d_min
  FROM  cd
 WHERE  d_min >= ALL ( SELECT d_min FROM cd );

Dotazy nad více tabulkami - druhy spojení

Při výběru z více tabulek je nutné z důvodu jednoznačnosti udávat plně kvalifikované názvy sloupců. Spojení je realizováno přes rovnost klíče (tituly.id) a cizího klíče (pisne.id) :

SELECT  tituly.id, tituly.titul, pisne.pisen, pisne.d_min, pisne.d_sec
  FROM  tituly, pisne
 WHERE  tituly.id = pisne.id;
Takovýto zápis dotazu může být poněkud zdlouhavý a proto jsou-li názvy vybíraných sloupců jednoznačné v rámci všech tabulek, není nutné udávat jejich plně kvalifikované názvy :
SELECT  titul, pisen, d_min, d_sec
  FROM  tituly, pisne
 WHERE  tituly.id = pisne.id;
Nejlepším řešením je však používání aliasů :
SELECT  t.interpret, t.id, p.pisen, p.d_min, p.d_sec
  FROM  tituly t, pisne p
 WHERE  t.id = p.id;

Spojení 3 tabulek :

Výpis kompletního rozvrhu předmětů :

SELECT  p.zkratka, r.semestr, r.den, r.h_od, r.h_do, m.zkratka
  FROM  predmety p, rozvrh r, mistnosti m
 WHERE  p.id = r.id_predm
   AND  r.id_mistn = m.id;
Left outer-join :

Syntax zápisu tohoto typu spojení není bohužel sjednocená, proto jsou uvedeny zápisy dotazů podle normy SQL2, pro Oracle a Informix.

Výpis rozvrhu předmětů včetně nerozvrhovaných :

Výpis rozvrhu předmětů včetně různých narozvrhovaných akcí :

Semi-join :

Výpis všech narozvrhovaných předmětů :

SELECT  p.zkratka, p.nazev
  FROM  predmety p
 WHERE  EXISTS ( SELECT  *
                   FROM  rozvrh r
                  WHERE  p.id = r.id_predm );

Dotaz lze napsat i takto :

SELECT  DISTINCT p.zkratka, p.nazev
  FROM  predmety p, rozvrh r
 WHERE  p.id = r.id_predm;

Výpis všech předmětů bez rozvrhu :

SELECT  p.zkratka, p.nazev
  FROM  predmety p
 WHERE  NOT EXISTS ( SELECT  *
                       FROM  rozvrh r
                      WHERE  p.id = r.id_predm );

Self-join :

Seznam osob s jejich přímým nadřízeným :

SELECT  a.prijmeni, a.jmeno, b.prijmeni, b.jmeno
  FROM  osoby a, osoby b
 WHERE  a.id_nad = b.id_osoby;