Skip to main content

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 výrazochprí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:

SELECT-- priezvisko,vypíše priezvisko a plat všetkých Petrov
SELECT last_name, salary
FROM zamestnanciemployees
WHERE menofirst_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 výrazom:príkazom:

SELECT * FROM zamestnanci;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)Oracle, teda po zadaní príkazu SET SQL_MODE = Oracle.

      Môžeme všaktiež použiť funkciu CONCAT(), ktorá funguje vo všetkých trochspomínaných SQL serveroch, napríklad:dialektoch.

      -- variant s ||
      SELECT last_name || ' zarába mesačne ' || salary
      FROM employees;
      
      -- variant s CONCAT
      SELECT CONCAT(meno,last_name, ' zarába mesačne ', plat)salary)
      FROM zamestnanci;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(meno,last_name, CONCAT(' zarába mesačne ', plat)salary))
      FROM zamestnanci;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;

      TrebaV daťtomto pozorprípade nasa rozdielykaždé jednotlivýchoddelenie databázovýchobjaví systémov:len raz.

        Slovo

        DISTINCT je rozlišovaniedodatok malýchk / veľkých písmen v texte:SELECT Oracle SQL a PostgreSQLnie ichpredpona rozlišujú,názvu MySQL/MariaDBstĺpca! nie;Výraz operáciaSELECT deleniaDISTINCT celýchfirst_name, čísel:last_name Oraclenebude SQLodstraňovať opakujúce sa krstné mená (a MySQL/MariaDB vrátia výsledok ako reálneby číslo,to PostgreSQLmal vrátirealizovať, akoktoré výsledokpriezvisko by vypísal?), ale odstráni len celúzamestnancov, časťktorí (rovnakomajú akorovnaké programovacímeno jazyki C++). priezvisko.