MS Access - Predikát TOP

17. 12. 2012, Vladimír Klaus, přečteno 4240x

MS Access
SQL

Pomocí tohoto příkazu získáme prvních X záznamů z tabulky, resp. dotazu. Ale pozor - ne všechny databáze tento příkaz podporují.

Upozornění: Tento predikát má další specifika, proto si prosím důkladně přečtěte celou tuto část, jinak získáte výsledky, které nemusí být korektní.

Následujícím příkazem získáme 5 nejstarších objednávek. A proč nejstarších? Protože v příkazu nemáme žádné řazení, takže to bude vlastně prvních 5 vložených záznamů do tabulky Objednávky.

SELECT TOP 5 * FROM Objednavky

SQL obrázek

Pokud bychom chtěli naopak 5 nejnovějších, pak je nutné specifikovat sestupné řazení dle data vložení nebo ještě lépe dle Id.

SELECT TOP 5 * FROM Objednavky ORDER BY Datum DESC

SQL obrázek

Podobně pak získáme například 4 největší objednávky. Aby to fungovalo, musíme použít sestupné řazení dle částky.

SELECT TOP 4 * FROM Objednavky ORDER BY Castka DESC

SQL obrázek

Aha! Pročpak je ve výsledku 6 řádek, když jsme chtěli jen 4? Je to proto, že systém nejprve zjistí 4 nejvyšší částky (4499, 2999, 1999 a 1790) a pak se snaží postupně zobrazit záznamy, které jim vyhovují. V případě 4499 jsou to jen 3 a to je málo, tak přidá další hodnotu 2999. Jenže tomu odpovídají 3 záznamy, takže výsledek je 6 záznamů. Další hodnoty už nejsou použity.

Chcete-li obejít toto zvláštní chování, přidejte do řazení nějaký sloupec, který nabývá unikátních hodnot – nejlépe Id. Pak už bude výsledek takový, jaký jste asi chtěli. Samozřejmě je otázkou, která z objednávek MP3 přehrávače má být zařazena do tohoto seznamu TOP 4…

SELECT TOP 4 * FROM Objednavky ORDER BY Castka DESC, Id

SQL obrázek

Následujícím příkazem získáme prvních 10 měst (podle abecedy), ve kterých bydlí naši zákazníci. Protože jsme již poučeni, přidáváme pro jistotu také Id.

SELECT TOP 10 Mesto, PSC FROM Zakaznici ORDER BY Mesto, Id

SQL obrázek

A je tu další problém – města se opakují. Že tam není 10 položek, je jasné – tolik měst v tabulce zákazníků není. Eliminaci duplicit vyřešíme pomocí klíčového slova DISTINCT, což ovšem znamená, že musíme vyhodit také Id z řadící podmínky.

SELECT DISTINCT TOP 10 Mesto FROM Zakaznici ORDER BY Mesto

SQL obrázek

Příkaz TOP se dá dokonce kombinovat ještě s textem „PERCENT“. Tím dosáhneme toho, že z výsledku dotazu bude zobrazeno jen požadované procento řádek.  To je velmi důležité si uvědomit – uvedená procenta nemají žádnou souvislost s hodnotami tabulky, ale pouze s počtem řádek!

Pokud by tedy následující výběr vrátil 22 řádek…

SELECT * FROM Objednavky ORDER BY Castka DESC

… pak tento výběr vrátí 35 % z 22, tedy 7,7 = 8 řádek.

SELECT TOP 35 PERCENT * FROM Objednavky ORDER BY Castka DESC

SQL obrázek

Tento predikát má ještě další a opět velmi užitečné použití. A to třeba když chcete získat úplně nejvyšší objednávku. Tím kouzlem je použití „TOP 1“.

SELECT TOP 1 * FROM Objednavky ORDER BY Castka DESC

SQL obrázek

Jak vidíte, opět zde došlo k vrácení nesprávného počtu záznamů, což je správně – 3 objednávky splňují podmínku na to, že jsou největší. Pokud ale opravdu potřebujete jen jednu, pak musíte opět kombinovat s řazením dle Id, případně s datem apod.

SELECT TOP 1 * FROM Objednavky ORDER BY Castka DESC, Id

SQL obrázek

V jiných databázích

V jiných databázích je nutné použít zcela jiný zápis, protože predikát TOP neznají.

V MySQL se 5 nejstarších objednávek získá takto:

SELECT * FROM Objednavky LIMIT 5

A v databázi Oracle zase takto:

SELECT * FROM Objednavky WHERE ROWNUM <= 5

Závěrečná poznámka

Jak vidíte, predikát TOP je nakonec docela komplikovaný. Dejte při jeho používání pozor a vždy ověřujte, zda vrací to, co opravdu chcete. Jinými slovy – důkladně testujte na dostatečně rozsáhlém vzorku dat a případně již odladěné dotazy ověřte, zda fungují i v jiné databázi.