Tentokrát se věnuji klauzuli SELECT, a jejím příkazům, podrobněji se podívám na JOINy a jejich typy. Jelikož SELECT a JOINy jsou pro DWH stěžějní je potřeba se u nich pozastavit.
SELECT je základním příkazem SQL. Pro DWH stěžejní. Slouží k získání dat z databáze. Struktura SELECTu je následující:
SELECT alias.COLUMN1, alias.COLUMN2, ... FROM DATABASE.SCHEMA.TABLE1 alias JOIN DATABASE.SCHEMA.TABLE2 tbl2 ON joinCondition1 JOIN DATABASE.SCHEMA.TABLE3 tbl3 ON joinCondition2 ... WHERE conditions GROUP BY alias.COLUMN1, alias.COLUMN2, … HAVING havingCondition ORDER BY alias.COLUMN1
V části SELECT specifikuji sloupce, které chci na výstup. Dobrou praxí je sloupce vždy vyjmenovávat. Ovšem existuje možnost zobrazit všechny sloupce pomocí symbolu *. * lze používat v kombinaci s aliasy – jednoduché pojmenování datového zdroje.
V části FROM se specifikuji zdroj, tabulka ze které čtu data. Zde je mohu uvést alias k tabulce – velmi doporučuji.
Následuje nepovinná část s JOINy. Pomocí JOINu lze připojit do SELECTu další tabulku. Tabulky je potřeba připojit na základě podmínky. Existuje několik typů joinu. Nejdůležitější jsou LEFT JOIN, INNER JOIN a FULL OUTER JOIN. Joinování tabulek rozeberu více do detailu později.
Další částí je nepovinná část WHERE. Ta umožnuje filtrovat nad zdrojovou tabulkou. Je možné si tu vymyslet různé podmínky od >=, =, <=, <, BETWEEN, LIKE, IN
atd. Podmínky se spojují klasickými spojkami z matematické logiky AND a OR.
SELECT a agregace
K agregaci dat slouží nepovinná část GROUP BY. Tu použiji typicky, když budu data agregovat pomocí funkcí jako je count(), sum(), avg(), min(), max()
a spousty dalších. Tyto funkce se zapisují do části SELECT. Pokud neagreguji nad celou tabulkou, ale dle konkrétního sloupce nebo více sloupců, tak tyto sloupce musím vyjmenovat do GROUP BY. Sloupce v GROUP BY a neagregované sloupce v SELECTu se musí shodovat. Agregační dotaz vypadá následovně:
SELECT alias.COLUMN1, alias.COLUMN2, sum(alias.COLUMN_X) as SUM_COLUMN_X FROM DATABASE.SCHEMA.TABLE1 alias GROUP BY alias.COLUMN1, alias.COLUMN2
S agregací také souvisí klauzule HAVING. Pokud potřebuji filtrovat pomocí agregovaného sloupce, nelze použít WHERE, ale je na to klauzule HAVING, kde toto lze provést. Jinak funguje stejně jako WHERE.
Pak je možné přidat nepovinnou část ORDER BY, která slouží k řazení. Prostě vyjmenuji sloupce podle, kterých chci řadit. Nebo můžu místo jejich názvů použít čísla, která reprezentují jejich pořadí v části SELECT. Řadit lze dvěma směry a to buď ASC (ascending) nebo DESC (descending).
Ještě bych chtěl uvést, že pokud pracuji s velkou tabulkou, není vhodné jí načítat do paměti celou při testování. A je dobré omezit počet načítaných řádků. Toto už se v různých dialektech SQL dělá různým způsobem. V postgreSQL lze použít klauzuli LIMIT a počet řádků LIMIT 10
. V Microsoft SQL Serveru se na začátku dotazu použije SELECT TOP 10
.
Kromě zdrojových tabulek v klauzulích FROM a JOIN lze použít subquery. To je jiný SQL dotaz, který obalím závorkami, použiji místo tabulky v daných klauzulích a je mým novým zdrojem a pracuji s ním stejně jako s tabulkou.
JOINy
JOIN je způsob jak propojovat data z různých tabulek v dotazu. V praxi využiji tři typy joinu a to jak už jsem zmínil výše INNER JOIN, LEFT OUTER JOIN a FULL OUTER JOIN. Joinování je pouze prací s množinami, takže to lze i hezky znázornit obrázkem. V tabulce pak všechny typy joinu.
K LEFT JOINu existuje i obrácená varianta RIGHT JOIN, ale bez ní se obejdu. V SQL pak lze používat zkrácený zápis INNER JOIN = JOIN, LEFT OUTER JOIN = LEFT JOIN a FULL OUTER JOIN = FULL JOIN
.

JOIN | WHERE podmínka | Popis | Matematický zápis |
INNER JOIN | Omezí výsledek pouze na záznamy co se propojí | (A ∩ B) | |
LEFT JOIN | Všechny záznamy z A, pokud v B záznam není, připojí se sloupce jako null | A | |
LEFT JOIN | B.KEY IS NULL | Ponechá pouze záznamy co se nepropojí | (A / B) |
RIGHT JOIN | Všechny záznamy z B, pokud v A záznam není připojí se sloupce jako null | B | |
RIGHT JOIN | A.KEY IS NULL | Ponechá pouze záznamy co se nepropojí | (B / A) |
FULL OUTER JOIN | Obě tabulky – pokud se někde nepropojí tak jsou sloupce null | (A ∪ B) | |
FULL OUTER JOIN | A.KEY IS NULL OR B.KEY IS NULL | Obě tabulky bez průniku – pokud se někde propojí tak tam záznamy nebudou | (A ∪ B) / (A ∩ B) |
CROSS JOIN | Každý s každým. cros join = inner join on 1 = 1 |
/* Inner join */ SELECT a.KEY, b.KEY FROM A a JOIN B b ON a.KEY = b.KEY /* Left join */ SELECT a.KEY, b.KEY FROM A a LEFT JOIN B b ON a.KEY = b.KEY /* Left join B is null */ SELECT a.KEY, b.KEY FROM A a LEFT JOIN B b ON a.KEY = b.KEY WHERE b.KEY IS NULL /* Full join */ SELECT a.KEY, b.KEY FROM A a FULL JOIN B b ON a.KEY = b.KEY /* Full join A or B is null*/ SELECT a.KEY, b.KEY FROM A a FULL JOIN B b ON a.KEY = b.KEY WHERE b.KEY IS NULL or a.KEY IS NULL
Pokud by Vás zajímalo co se pod joinem skrývá. Tomu se plánuji věnovat později v článku co bude mít název Optimalizace, kde se je potřeba podívat hlouběji, abychom mohli úspěšně dotazy optimalizovat.
Shrnutí
- Nejdůležtějším SQL příkazem v DWH je SELECT a má strukturu s klauzulemi SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING a ORDER BY. V SELECTu jsou sloupce, FROM specifikuje zdrojovou tabulku, JOIN umožňuje připojovat další tabulky, WHERE je pro filtrování, GROUP BY pro agregace, HAVING umožňuje filtrovat nad agregacemi a ORDER BY řadí.
- JOIN připojuje další tabulky a má několik typů: INNER JOIN, LEFT JOIN a FULL JOIN. Kromě těchto typů lze jejich chování ovlivnit v klauzuli WHERE pomocí podmínky IS (NOT) NULL.
Doporučené články
Předchozí články
Co je to datový sklad (DWH)? – 1. díl
Základní tipy v datovém skladu (DWH) – 2. díl
Vrstvy datového skladu (DWH) – 3. díl
Následující článnky
Pojmenovávání a dokumentace – 8. díl
Orchestrace (noční load) – 9. díl
Pokročilé agregační funkce – 10. díl
Příklady
Příklady použití SELECT Examples.SELECT
Nastavení DWH v PostgreSQL – 1.příklady
User-defined funkce – 3. příklady
Windowed functions – 6. příklady
Dokumentace
PostgreSQL https://www.postgresql.org/docs/16/queries-table-expressions.html
MSSQL https://learn.microsoft.com/en-us/sql/t-sql/lesson-1-creating-database-objects?view=sql-server-ver16
MSSQL JOIN https://learn.microsoft.com/en-us/sql/relational-databases/performance/joins?view=sql-server-ver16