Ve spolupráci se SEDUO jsem vytvořil několik videokurzů:
V tomto článku se podíváme jak na SELECT s WHERE. Aneb proč nechat trápit Excel, když si z databáze můžete vytáhnout jen to co potřebujete?
Primárně jsou ukázky v MySQL, ale není problém využít MSSQL, atd.
Využijete v Power Query pokud chcete data načítat rovnou z databáze (ušetříte vypočetní výkon v Excel). Tento článek je jako pomůcka, ať nemusíte stále využívat Excel (a tahat vše). Ukázky rovnou můžete testovat v databázi. Ale klidně testujte přímo v Excel.
Trochu jsme se rozepsal, tak jsme článke rozdělil na jednotlivé podkapitoly, ať se můžete rycheji zorientovat, pokdu potřebujete najít konkretní SELECT.
Primárně využívám MySQL, která je zdarma a dá se využít i na online na phpmyadmin.
Předpokládám, že do databáze máte přístup a víte jaké tabulky v ní máte, popřipádě si do databáze tabulku s daty umíte přidat (v přípravě podrobné články jak na to, pokud bude zájem).
V dalších ukázkách budu využívat tabulku studenti, které má tyto sloupce. Záměrně některé sloupce mají chyby atd.
| Sloupec | Datový typ | Popis |
|---|---|---|
| id | int | AUTO_INCREMENT Primární klíč, generuje se automaticky |
| jmeno | varchar(60) | Křestní jméno studenta |
| prijmeni | varchar(60) | Příjmení studenta |
| pohlavi | varchar(1) | M = muž, F = žena |
| plat | int | Měsíční výdělek studenta (demonstrační data) |
| datum_narozeni | date | Datum narození ve formátu RRRR-MM-DD |
| mesto | varchar(20) | Město, ze kterého student pochází |
| fakulta | varchar(4) | Zkratka fakulty (max. 4 znaky) |
| abcd | varchar(2) | Pomocný sloupec pro cvičení |
| test | int | Číslo fakulty — přes nešťastný název sloupce |
Poud máte do své databáze přístup i na vkládaní tabulek a dat do tabulek můžete využít přiložený SQL dotaz.
-- Vytvoření tabulky
CREATE TABLE `studenti` (
`id` int AUTO_INCREMENT,
`jmeno` varchar(60),
`prijmeni` varchar(60),
`pohlavi` varchar(1),
`plat` int,
`datum_narozeni` date,
`mesto` varchar(20),
`fakulta` varchar(4),
`abcd` varchar(2),
`test` int,
PRIMARY KEY (`id`)
);
-- naplnění tabulky daty
insert into studenti values ('1', 'Jana', 'Kratka', 'F', '23500', '1954-12-22', 'Brno', 'ESF', 'A', '0');
insert into studenti values ('2', 'Jana', 'Nováková', 'F', '42261', '2016-11-11', 'Brno', 'ESF', 'a', '1');
insert into studenti values ('3', 'Sophia', 'Santiago', 'F', '20758', '1962-11-16', 'Brno', 'ESF', 'á', '8');
insert into studenti values ('4', 'Jarek', 'Benes', 'M', '52483', '2017-06-11', 'Praha', 'ESF', '1', '8');
insert into studenti values ('5', 'Petr', 'Malý', 'M', '10000', '2001-09-23', 'Praha', 'ESF', '0', '8');
insert into studenti values ('6', 'Honza', 'Adamec', 'M', '29990', '1977-07-27', 'Praha', 'ESF', 'c', '7');
insert into studenti values ('7', 'Petra', 'Adamcova', 'F', '23500', '1982-03-16', 'Olomouc', 'ESF', 'ch', '6');
insert into studenti values ('8', 'Zuzka', 'Bezva', 'F', '39752', '2016-02-29', 'Ostrava', 'ESF', 'i', '7');
insert into studenti values ('9', 'Ivan', 'Sobota', 'M', '15274', '1900-02-01', 'Pardubice', 'ESF', 'h', '3');
insert into studenti values ('10', 'Petr', 'Novak', 'M', '27679', '2002-05-20', 'Opava', 'ESF', 'Z', '2');
Než se pustíme do jednotlivých příkazů, je dobré vidět celou stavbu příkazu SELECT pohromadě. Oficiální popis najdete v referenční příručce MySQL v kapitole SELECT Statement na adrese dev.mysql.com. Zjednodušený zápis nejpoužívanějších klauzulí vypadá takto:
SELECT [ALL | DISTINCT] select_expr [, select_expr] ...
FROM table_references
WHERE where_condition
GROUP BY {nazev_sloupce | výraz | pozice} [WITH ROLLUP]
HAVING where_condition
WINDOW nazev_okna AS (specifikace_okna)
ORDER BY {nazev_sloupce | výraz | pozice} [ASC | DESC]
LIMIT {[offset,] pocet_radku | pocet_radku OFFSET offset}
SELECT je jediná povinná část — dotaz SELECT 1 + 1; funguje i bez tabulky. Vše ostatní si přidáváte podle potřeby.
Dokumentace MySQL to formuluje jednoznačně. Klauzule musí být zapsány přesně v pořadí uvedeném v popisu syntaxe. Konkrétně HAVING musí následovat po GROUP BY a předcházet ORDER BY. Pokud pořadí zaměníte, dotaz skončí syntaktickou chybou.
Je to jako se školou. Nejdřív mateřská škola, pak základní škola, nakone auto-škola. Tj - posloupnost se přeskakovat nedá.
Nejjednodušší dotaz vypíše všechny sloupce a všechny řádky tabulky. Třeba na kontrolu, zda vše funguje jak má.
SELECT * FROM studenti;
Každý příkaz ukončujeme středníkem a potvrzujeme, klikem na příslušnou ikonu. Nebo klávesovou zkratkou (v MySQL Workbench Ctrl + Enter).
V některých materiálech se dočtete o zápisu s ALL. ALL (všechno) je výchozí chování (vypiš všechny záznamy včetně duplicit) a v MySQL jej psát nemusíte. Dotaz funguje naprosto stejně i bez něj. Opakem ALL je DISTINCT.
SELECT ALL * FROM studenti;
Poznámky jsou v SQL k nezaplacení, (možná v době AI vám to vysvtělí, ale pročř stále otravovat AI?). Zvlášť když si stavíte vlastní knihovnu dotazů.
-- Jednořádkový komentář (dva spojovníky a mezera)
/* Víceřádkový komentář
první řádek
druhý řádek */
SELECT - výběr sloupců
Místo hvězdičky uvedeme názvy sloupců oddělené čárkou. Polkud tabulka studenti obsahuje sloupec jmeno:
SELECT jmeno FROM studenti;
potažno pokud chcete jmeno a prijemni
SELECT jmeno, prijmeni FROM studenti;
Co ale pokud zapomenete čárku
SELECT jmeno prijmeni FROM studenti;
Dotaz nezhavaruje — a to je právě zrada. Vypíše se jediný sloupec, ve kterém jsou jména, ale v záhlaví je napsáno „prijmeni". MySQL totiž druhé slovo pochopilo jako alias (nový název) prvního sloupce. Je to „dobrá chyba" k zapamatování: pokud vám ve výsledku chybí sloupec a jiný má divný název, hledejte chybějící čárku.
Hlavně nezapomenout na čárku!
Alias je vlastní název sloupce ve výsledku dotazu. Zapisuje se klíčovým slovem AS:
SELECT jmeno AS krestni_jmeno, prijmeni AS prijmeni_studenta
FROM studenti;
Slovo AS lze vypustit (viz past výše), ale doporučuji ho psát — je pak zřejmé, že jde o záměr, a ne o zapomenutou čárku.
Chcete-li v názvu mezeru, uzavřete alias do zpětných apostrofů ` ` (na české klávesnici AltGr + 7`; po napsání znaku je potřeba stisknout Enter, aby se znak potvrdil):
SELECT jmeno AS `Celé jméno`, prijmeni AS `Příjmení studenta`
FROM studenti;
Můžete se setkát i s jinými zápisy, které fungovat nemusí nebo dělají něco úplně jiného:
-- Někdy funguje, někdy ne (závisí na databázi):
SELECT (jmeno) FROM studenti;
-- POZOR: toto NENÍ sloupec, ale textová konstanta!
SELECT "jmeno" FROM studenti;
Zaleží co a kde se vyhodnocuje. Viz ještě dále.
-- FUNGUJE — ORDER BY se vyhodnocuje až po SELECT
SELECT plat * 10 AS novy_plat FROM studenti ORDER BY novy_plat DESC;
-- NEFUNGUJE — WHERE se vyhodnocuje dřív než SELECT
SELECT plat * 10 AS novy_plat FROM studenti WHERE novy_plat > 100000;
-- Řešení: zopakovat celý výraz
SELECT plat * 10 AS novy_plat FROM studenti WHERE plat * 10 > 100000;
Máte-li práva, můžete číst i z jiné databáze, než ve které se právě nacházíte. Stačí uvést název databáze před název tabulky.
SELECT * FROM nazev_databaze.studenti;
DISTINCT odstraní z výsledku duplicitní řádky:
SELECT DISTINCT pohlavi FROM studenti;
DISTINCT se vztahuje na celý řádek, ne na jeden sloupec, Tento dotaz vrátí unikátní kombinace — pokud jsou v Opavě muži i ženy, dostanete dva řádky: „muži z Opavy" a „ženy z Opavy".
SELECT DISTINCT pohlavi, mesto FROM studenti;
Podrobněji se podíváme na funkce a výpočty ve sloupcích v samostatném článku, ale hodí se jen do kontextu.
SELECT jmeno, plat, plat * 10 AS `Nový plat`
FROM studenti;
Původní sloupec plat zůstane nedotčený — výpočet vytvoří nový sloupec ve výstupu. Bez aliasu by se sloupec jmenoval doslova plat * 10, což je nepraktické.
Zatímco SELECT vybírá sloupce, WHERE vybírá řádky. Aneb získat studenty z Brna...
SELECT * FROM studenti
WHERE mesto = "Brno";
V nápovědách můžete najít různé ruzné znaky uvozovky, atd. Nejlépší je používat apostrofy.
WHERE mesto = "Brno" -- funguje
WHERE mesto = 'Brno' -- funguje (apostrofy)
WHERE mesto = `Brno` -- NEFUNGUJE — zpětné apostrofy = identifikátor
WHERE mesto = Brno -- NEFUNGUJE — bez uvozovek to není text
Zvlášť pozor při přechodu mezi různými databázovými nástroji — chování se může lišit. Nejbezpečnější je používat jednoduché apostrofy 'Brno'.
| Operátor | Význam | Příklad |
|---|---|---|
| = | rovná se | WHERE pohlavi = ‚F‘ |
| <> | nerovná se | WHERE pohlavi <> ‚F‘ |
| != | nerovná se (totéž co <>) | WHERE pohlavi != ‚F‘ |
| > | větší než | WHERE test > 6 |
| < | menší než | WHERE test < 6 |
| >= | větší nebo rovno | WHERE test >= 6 |
| <= | menší nebo rovno | WHERE test <= 8 |
Viz dále operátor <=> pro porovnání bezpečně vůči NULL.
Zda databáze při porovnávání rozlišuje velikost písmen, nezávisí na SQL příkazu, ale na nastavení porovnávací sady — collation — u daného sloupce, tabulky nebo databáze. Ve výchozím nastavení MySQL velikost písmen nerozlišuje, takže:
SELECT * FROM studenti WHERE mesto = 'brno'; -- vrátí i záznamy "Brno"
Pokud chcete zjistit (opět v samostatném článku podrobněji).
-- Collation jednotlivých sloupců tabulky
SHOW FULL COLUMNS FROM studenti;
-- Collation celé tabulky
SHOW TABLE STATUS LIKE 'studenti';
-- Collation aktuální databáze
SELECT @@collation_database;
-- Přehled dostupných collationů
SHOW COLLATION WHERE Charset = 'utf8mb4';
Typické hodnoty v MySQL 8: utf8mb4_0900_ai_ci (výchozí, nerozlišuje nic), utf8mb4_0900_as_cs (rozlišuje diakritiku i velikost písmen), utf8mb4_bin (bajt po bajtu).
Pokud máte možnost, víte co děláte. V samosatném článku podrobněji.
-- 1) Jen pro jeden konkrétní dotaz (nic v databázi se nemění)
SELECT * FROM studenti
WHERE mesto COLLATE utf8mb4_0900_as_cs = 'Brno';
-- 2) Natrvalo pro jeden sloupec
ALTER TABLE studenti
MODIFY mesto VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;
-- 3) Natrvalo pro celou tabulku (převede všechny textové sloupce)
ALTER TABLE studenti
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;
-- 4) Pro databázi — platí pro nově vytvářené tabulky
ALTER DATABASE nazev_databaze
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;
Rychlá jednorázová alternativa bez změny schématu je porovnání jako binární data:
SELECT * FROM studenti
WHERE CAST(mesto AS BINARY) = CAST('Brno' AS BINARY);
AND — musí platit obě podmínky zároveň:
SELECT * FROM studenti
WHERE pohlavi = 'F' AND mesto = 'Brno';
OR — stačí, aby platila alespoň jedna podmínka:
SELECT * FROM studenti
WHERE pohlavi = 'F' OR mesto = 'Brno';
Chceme studenty s testem od 6 do 8 bodů včetně. Správně:
SELECT * FROM studenti
WHERE test >= 6 AND test <= 8;
Kdybychom napsali OR, dostaneme všechny řádky:
-- CHYBA: vrátí úplně všechno
WHERE test >= 6 OR test <= 8;
NULL znamená chybějící nebo neznámou hodnotu. Není to nula ani prázdný text — je to informace „nevíme". Protože v naší tabulce nemá žádný sloupec kromě id uvedeno NOT NULL, může se NULL objevit kdekoli: student, u kterého neznáme plat, nemá vyplněné město, chybí datum narození nebo nepsal test.
MySQL Workbench zobrazuje takové buňky jako šedý nápis NULL.
NULL se nadá porovnat s rovnítkem
-- NEFUNGUJE — vrátí prázdný výsledek, i když NULL v datech jsou
SELECT * FROM studenti WHERE plat = NULL;
-- SPRÁVNĚ
SELECT * FROM studenti WHERE plat IS NULL;
Důvod: NULL není hodnota, ale absence hodnoty. Otázka „rovná se neznámá hodnota neznámé hodnotě?" nemá odpověď ano/ne — výsledkem porovnání je opět NULL, což se ve WHERE chová jako nesplněná podmínka. Proto existují speciální operátory:
SELECT * FROM studenti WHERE plat IS NULL; -- studenti bez uvedeného platu
SELECT * FROM studenti WHERE plat IS NOT NULL; -- studenti s vyplněným platem
SELECT * FROM studenti WHERE mesto IS NULL; -- chybí město
SELECT * FROM studenti WHERE test IS NOT NULL; -- test napsali
Pozor na nerovná se s null.
SELECT * FROM studenti WHERE mesto <> 'Brno';
Tento dotaz nevrátí studenty, kteří mají mesto prázdné (NULL). Intuitivně bychom čekali, že „město není Brno" platí i pro toho, kdo město nemá vyplněné — ale databáze na to odpovídá „nevím", a nevím se do výsledku nedostane. Pokud je chcete zahrnout, musíte to říct výslovně:
SELECT * FROM studenti
WHERE mesto <> 'Brno' OR mesto IS NULL;
Stejná past číhá u NOT IN:
-- Pokud je v seznamu NULL, dotaz nevrátí NIC
SELECT * FROM studenti WHERE jmeno NOT IN ('Pavel', 'Petr', NULL);
Agregační funkce hodnoty NULL ignorují — a to je nejčastější zdroj tichých chyb v reportech. Kdy o agregačních funkcích se ještě budeme bavit:
SELECT
COUNT(*) AS pocet_radku, -- počítá všechny řádky
COUNT(plat) AS pocet_s_platem, -- počítá jen NEprázdné hodnoty
AVG(plat) AS prumer, -- průměr jen z vyplněných hodnot
SUM(plat) AS soucet
FROM studenti;
Pokud má polovina studentů plat nevyplněný, AVG(plat) počítá průměr jen z té druhé poloviny — ne z celého počtu studentů. Rozdíl mezi COUNT(*) a COUNT(plat) je proto rychlá kontrola, kolik hodnot vám v datech chybí.
Budu se zabývat ve specialitách:
-- IFNULL — dvě hodnoty
SELECT jmeno, IFNULL(mesto, 'neuvedeno') AS mesto FROM studenti;
-- COALESCE — vrátí první nenulovou hodnotu ze seznamu (standardní SQL)
SELECT jmeno, COALESCE(mesto, 'neuvedeno') AS mesto FROM studenti;
-- Průměr, kde se prázdný plat počítá jako nula
SELECT AVG(IFNULL(plat, 0)) AS prumer_vcetne_nul FROM studenti;
Doplnění, v samostatném souboru.
SELECT NULL = NULL; -- vrátí NULL
SELECT NULL <=> NULL; -- vrátí 1 (pravda)
Nezapominejme ani na řazení a filtrování což je popsáno dále:
SELECT mesto, COUNT(*) AS pocet
FROM studenti
GROUP BY mesto
ORDER BY mesto ASC; -- řádek s NULL bude první
Shrnutí v jedné větě: na NULL se ptejte výhradně pomocí IS NULL / IS NOT NULL a u každé agregace si uvědomte, že prázdné hodnoty do výpočtu nevstupují.
Když neznáme přesnou hodnotu, použijeme LIKE se zástupnými znaky:
pár ukázek
WHERE jmeno LIKE 'J%' -- vše, co začíná na J (Jan, Jana, Jindřich…)
WHERE jmeno LIKE '%a' -- vše, co končí na a
WHERE jmeno LIKE '%an%' -- vše, co obsahuje "an"
WHERE jmeno LIKE 'JA_' -- JA + právě 1 znak › "Jan"
WHERE jmeno LIKE 'JA__' -- JA + právě 2 znaky › "Jana"
WHERE jmeno NOT LIKE 'J%' -- vše, co NEzačíná na J
Podtržítka lze řetězit — každé zastupuje právě jeden znak. Kombinace 'JA_%' znamená „JA, pak alespoň jeden znak a pak cokoli".
Pozor na NULL: ani LIKE, ani NOT LIKE nevrátí řádky, kde je porovnávaný sloupec prázdný.
Místo dlouhého řetězce podmínek s OR použijeme IN. Hlavně u poddotazu atd. Případně se může hodit na parametrické hledání v Excel, kdy Power Query umí list. Což je vlastně seznam, který předáte IN.
SELECT * FROM studenti
WHERE jmeno IN ('Pavel', 'Petr');
Opak IN je NOT IN
SELECT * FROM studenti
WHERE jmeno NOT IN ('Pavel', 'Petr');
Omezení: LIKE a IN nelze zkombinovat — něco jako WHERE jmeno LIKE IN ('J%', 'P%') neexistuje. Řešením jsou regulární výrazy (REGEXP / RLIKE), kterým se věnuje samostatná lekce.
BETWEEN je čitelnější alternativa k dvojici podmínek s AND:
SELECT * FROM studenti
WHERE test BETWEEN 6 AND 8;
Hranice jsou zahrnuty — tento dotaz je ekvivalentní zápisu:
test >= 6 AND test <= 8
NOT BETWEEN vrátí opak, tedy hodnoty mimo interval 6–8 (obě hranice vyloučeny).
SELECT * FROM studenti
WHERE test NOT BETWEEN 6 AND 8;
Častý požadavek: mít jméno a příjmení v jednom sloupci. Zápisy, které znáte z jiných databází nebo z Excelu, v MySQL nefungují, bude zmíněno v článku o funkcích. Zde jen zmínka.
-- NEFUNGUJE podle očekávání:
SELECT jmeno || prijmeni FROM studenti; -- || je v MySQL logické OR
SELECT jmeno + prijmeni FROM studenti; -- + je aritmetické sčítání › výsledek 0
Funkce
SELECT CONCAT(jmeno, ' ', prijmeni) AS `Celé jméno`
FROM studenti;
-- Nebo s automatickým oddělovačem:
SELECT CONCAT_WS(' ', jmeno, prijmeni) AS `Celé jméno`
FROM studenti;
Rozdíl při NULL: pokud je kterýkoli argument CONCAT() prázdný, je výsledkem NULL — přijdete o celé jméno. CONCAT_WS() naproti tomu prázdné hodnoty přeskočí. To je hlavní důvod, proč sáhnout po CONCAT_WS(). Viz samostatný článek.
Požadavek na omezení počtu řádku, například pro testy ať nenatahujete všehchny data, ale jen určtý vzorek.
SELECT * FROM studenti
LIMIT 10; -- prvních 10 řádků
SELECT * FROM studenti
LIMIT 5; -- prvních 5 řádků
Natáhnete si jen požadovaný počet řádků.
Pokud chcete od určitého řádku danný počet řádků. To asi nevyužijete, ale info, že jde. Teda chápu ve výpočtech top 5 produktů, ale to se vsadím, že využijete DAX (nebo se pletu?).
LIMIT se dvěma argumenty určuje první číslo posun (offset) a druhé počet řádků. Číslování začíná nulou (ale to vás asi nepřekvapuje). Proto už víte proč indexování v Power Query má teké volbu od nuly.
SELECT * FROM studenti LIMIT 5, 10; -- řádky 6 až 15
SELECT * FROM studenti LIMIT 10 OFFSET 5; -- totéž, čitelnější zápis
Doporučení! LIMIT používejte vždy v kombinaci s ORDER BY. Bez řazení není zaručeno, které řádky dostanete. Databáze může řádky vrátit v libovolném pořadí. Viz samostatný článek na řazení.
Se SELECT se pojí další možností, kdy data můžete seřadit, seskupit, mít seskupená data jako podmínky, Přidat Window funkce, klasické funkce atd.
V přípravě
Narazili jste na nějaké problémy, máte tip na vylepšení nebo doplnění článku, můžete se zmínit v komentářích.
Článek byl aktualizován: 29.07.2026 22:09
Pomohl vám článek? Vyřešili jste problém? Můžete mě podpořit zakoupení tabulky (samozdřejmě čokoládové), když kafe nepiji ;) Odkaz na zakoupení čokolády. Za veškerou podporu vám děkuji a samozdřejmě jí využiji do zdokonalování a rozšířování webu.
Případně přidejte odkaz na vaši oblíbenou sociální síť, případně využijste hashtag #JakNaExcel .
Děkuji za váš čas a doufám, že jste nalezli odpověď na svůj problém.
Narazili jste v článku na nejasnost, chybu? Máte tip na vylepšení nebo doplnění článku? Budu rád pokud se zmínite v komentářích.
Microsoft Office (Word, Excel, Google tabulky, PowerPoint) se věnuji od roku 2000 (od dubna roku 2004 na této doméně) - V roce 2017 jsem od Microsoft získal prestižní ocenění MVP (zatím 8x za sebou). Své vědomosti a zkušenosti dávám k dispozici i on-line ve videích pro SEDUO. Ve firmách školím a konzultuji, učím na MUNI. Tento web již tvořím přes 20 let (o Excel píší přes 25). Zdarma je zde přes 1.500 návodu, tipů a triků, včetně přes 350 různých šablon, sešitů a přes 70 taháků v pdf.
|
Pomohl Vám návod? Sdílejte na Facebooku, G+ |
||
|
LinkedIn... |
Stránky o MS Office (Excel) produktu společnosti Microsoft. Neslouží jako technická podpora.
| Email na autora: pavel.lasak@gmail.com | Copyright © : Pavel Lasák 2004 - 2025 |