2.5 Výberový dopyt
Príkaz SELECT
Na získanie údajov z databázy používame takzvaný výberový dopyt s príkazom SELECT. Môžeme ho doplniť o selekciu riadkov klauzulou WHERE a tiež potlačiť duplicitné riadky výstupu kľúčovým slovom DISTINCT:
SELECT[DISTINCT]{stĺpce alebo výrazy}- FROM {tabuľka}
- [WHERE {podmienka}];
V záujme prehľadnosti je vhodné každú klauzulu písať na samostatný riadok – pri krátkych príkazoch dopytu sa to zdá zbytočné, no neskôr je to priam nutnosť. Napríklad môžeme zobraziť priezvisko a plat všetkých Petrov:
-- vypíše priezvisko a plat všetkých Petrov
SELECT last_name, salary
FROM employees
WHERE first_name = 'Peter';
Odlišnosť dialektov SQL: V Oracle SQL a PostgreSQL sa rozlišujú malé a veľké písmená v textoch, no v MySQL/MariaDB nie. SQL výrazy sa snažme písať univerzálne, teda počítajme s tým, že sa veľkosť písmen bude rozlišovať.
Projekcia a selekcia
Podmienkou WHERE filtrujeme riadky, nazývame to selekcia a voľbu stĺpcov nazývame projekcia. Pokiaľ chceme zobraziť všetky stĺpce, nemusíme ich menovať, ale môžeme použiť symbol „*“ – všetky informácie o všetkých zamestnancoch získame príkazom:
SELECT * FROM employees;
Operátory v klauzule SELECT
Aritmetické operátory
V každom programovacom jazyku môžeme používať matematiku, inak to nie je ani v SQL. Základné aritmetické operácie vykonáme rovnakými operátormi ako v jazykoch C++ či Python:
- sčítanie:
+ - odčítanie:
- - násobenie:
* - delenie:
/
-- vypíše 15 % z hodnoty platu pre každého zamestnanca
SELECT last_name, first_name, salary * 0.15
FROM employees;
Výsledok výpočtu sa len zobrazí, databázové údaje sa nijako nezmenia.
Pri vyhodnocovaní zložitejších aritmetických výrazov sa rešpektuje priorita (precedencia) operátorov – násobenie a delenie majú prednosť pred sčítaním a odčítaním. Samozrejme, prioritu môžeme ovplyvniť zátvorkami.
-- vypíše plat, relatívnu províziu (v percentách) a plat s províziou
SELECT
last_name,
salary,
commission_pct * 100,
salary * (1 + commission_pct)
FROM employees;
Odlišnosť dialektov SQL: Pri delení dvoch celých čísel Oracle SQL a MySQL/MariaDB vrátia výsledok ako reálne číslo, no PostgreSQL vráti ako výsledok len celú časť (rovnako ako programovací jazyk C++). Teda napríklad 22 / 7 bude 3.
Hodnota NULL
Pri riešení ERD sme rozlišovali povinné a voliteľné atribúty. Čo to vlastne znamená v reálnej databáze? Z atribútu sa stal stĺpec a pokiaľ je nepovinný, niektoré riadky tabuľky nebudú mať hodnotu uvedenú. Znamená to, že budú obsahovať číslo nula? Nie, pre tento prípad SQL jazyk pozná špeciálnu hodnotu NULL. Označuje nepriradenú / neznámu hodnotu.
Dôležité je vedieť, že pokiaľ sa vo výraze vyskytne NULL hodnota, výsledok bude NULL, a to dokonca aj v prípade, že by sme hodnotou NULL delili. Teda napríklad 100 / NULL nie je chyba, ale NULL. V predošlom príklade budú mať zamestnanci bez uvedenej provízie (3. stĺpec) aj v poslednom stĺpci hodnotu NULL.
Aliasy
V predošlých príkladoch sme si iste všimli, že tabuľka s výsledkami nevyzerala veľmi pekne – ak niektorý stĺpec získavame výrazom, v záhlaví je uvedený buď celý tento výraz alebo len zmienka o výraze. To môžeme zmeniť vďaka aliasu stĺpca. Alias určuje, čo bude zobrazené v záhlaví tabuľky s výsledkami. Môžeme ho zapísať troma spôsobmi:
- kľúčovým slovom AS:
SELECT {výraz} AS {alias} - využitím (dvojitých) úvodzoviek:
SELECT {výraz} "{alias}" - kombináciou oboch:
SELECT {výraz} AS "{alias}"
Platí pritom, že pokiaľ alias obsahuje medzery alebo špeciálne znaky, musí byť v (dvojitých) úvodzovkách.
-- vypíše plat, relatívnu províziu (v percentách) a plat s províziou
SELECT
last_name AS priezvisko,
salary AS plat,
commission_pct * 100 AS "percentá provízie",
salary * (1 + commission_pct) AS "plat s províziou"
FROM employees;
Hoci sa zdá pomenovávanie stĺpcov s výsledkami zbytočné, nie je to tak. Výstup z databázy spracováva program našej aplikácie a jej programátor sa spolieha, že sme stĺpce výsledkov pomenovali presne tak, ako sme sa dohodli.
Spájanie hodnôt
V klauzule SELECT môžeme spájať jednotlivé stĺpce a tiež ľubovoľné texty ohraničené apostrofmi ('). Oracle SQL a PostgreSQL umožňujú jednoduché spájanie operátorom dvojitej zvislej čiary (||) – je to síce SQL štandard, ale nefunguje v MySQL a v MariaDB len v režime Oracle, teda po zadaní príkazu SET SQL_MODE = Oracle.
Môžeme tiež použiť funkciu CONCAT(), ktorá funguje vo všetkých spomínaných SQL dialektoch.
-- variant s ||
SELECT last_name || ' zarába mesačne ' || salary
FROM employees;
-- variant s CONCAT
SELECT CONCAT(last_name, ' zarába mesačne ', salary)
FROM employees;
Žiaľ, v Oracle SQL môže mať funkcia CONCAT() len dva parametre, takže vyššie uvedený príklad by mal v univerzálnej podobe zložitejší tvar:
SELECT CONCAT(last_name, CONCAT(' zarába mesačne ', salary))
FROM employees;
Eliminácia duplikátov
Niekedy potrebujeme eliminovať duplicitné riadky vo výsledkoch. Ak by sme napríklad chceli vidieť čísla všetkých oddelení, v ktorých pracujú naši zamestnanci, bežný SELECT dopyt by nám zobrazil toľko čísel, koľko máme zamestnancov v oddeleniach. Každé oddelenie by sa opakovalo toľkokrát, koľko zamestnancov v ňom robí.
Duplikáty eliminuje kľúčové slovo DISTINCT hneď za SELECT:
SELECT DISTINCT department_id
FROM employees;
V tomto prípade sa každé oddelenie objaví len raz.
Slovo DISTINCT je dodatok k SELECT a nie predpona názvu stĺpca! Výraz SELECT DISTINCT first_name, last_name nebude odstraňovať opakujúce sa krstné mená (a ako by to mal realizovať, ktoré priezvisko by vypísal?), ale odstráni len zamestnancov, ktorí majú rovnaké meno i priezvisko.