Cílem této části je první náhled na způsob práce s databází.
Měli byste umět zjistit údaje o tabulce (SHOW) a použít příkaz SELECT pro následující úlohy:
Projděte si a vyzkoušejte následující SQL příkazy, které byly předmětem cvičení. V příštím cvičení budeme ještě pokračovat v tomto duchu. Na konci této stránky jsou příklady na procvičení. Taky doporučuji postupně si procházet tutoriály z úvodní stránky - buď jen věci, které jsme zatím probrali, nebo můžete zkoušet i něco dalšího.
Tento příkaz zkopíruje tabulku ctenari z databáze vik do vaší vlastní databáze, kde s ní můžete pracovat.
Proveďte bez dalšího přemýšlení:
create table ctenari select * from vik.ctenari;
Příkaz pro výpis seznamu databází:
show databases;
Příkaz pro výpis tabulek v aktuální databázi:
show tables;
Měli byste vidět dvě tabulky: sqls a zkopírovanou ctenari.
Je možné použít tlačítko .
Výpis tabulek v jiné databázi (vik):
show tables from vik;
Výpis tabulky s popisem sloupců:
describe sqls;
describe ctenari;
Zatím nás zajímají první dva sloupce: název a typ.
Na tlačítku .
Výpis obsahu všech sloupců a všech řádků tabulky:
select * from sqls;
select * from ctenari;
Možno použít tlačítko .
Celá tabulka v jiné databázi:
select * from vik.ctenari;
Tabulka sqls bude obsahovat příkazy, uložené pomocí .
Tlačítkem si ji můžeme vypsat:
select * from sqls order by name;
Hvězdička za SELECT znamená "všechny sloupce":
select * from ctenari;
Můžeme určit, které sloupce z tabulky chceme vypsat:
select jmeno,status from ctenari;
Pořadí může být libovolné:
select status,jmeno from ctenari;
Pomocí slova AS můžeme sloupec přejmenovat (alias):
select status,jmeno as příjmení from ctenari;
AS se může vynechat, ale raději ho používejte:
select status,jmeno příjmení from ctenari;
Pokud je alias víceslovný, musíme použít některý pár uvozovek/apostrofů:
select status,jmeno as 'příjmení a jméno' from ctenari;
select status,jmeno as "příjmení a jméno" from ctenari;
select status,jmeno as `příjmení a jméno` from ctenari;
Toto je chybné:
select status,jmeno as příjmení a jméno from ctenari;
Toto je taky chyba, sloupec `příjmení a jméno` v tabulce neexistuje:
select status,`příjmení a jméno` from ctenari;
Dva aliasy:
select status as `st`,jmeno as `příjmení a jméno` from ctenari;
select status as st,jmeno as `příjmení a jméno` from ctenari;
Toto je chyba, alias musí být jen pro jeden sloupec, ne pro všechny:
select * as xyz from ctenari;
Znovu výpis celé tabulky:
select * from ctenari;
Když chceme omezit výpis na určité řádky, zadáme omezovací podmínku za WHERE:
select * from ctenari where status='student';
select * from ctenari where status='učitel';
Podmínka může být složená. Používají se logické (AND, OR, NOT) a aritmetické (+ - = > < ...) operátory (budeme probírat později):
select * from ctenari where status='student' and platnost<'2005-1-1';
select * from ctenari where status='student' and platnost='2005-1-1';
select * from ctenari where status='student' and platnost>'2005-1-1';
Omezení jak sloupců tak řádků:
select id,platnost from ctenari where status='student' and platnost>'2005-1-1';
Ukázka použití funkce ve výrazu. Funkce se skládá z názvu a kulatých závorek, ve kterých jsou případné argumenty
Mezi názvem a levou závorkou NESMÍ být mezera.
Zde funkce now() udává aktuální datum a čas:
select id,platnost from ctenari where status='student' and platnost<now();
select id,platnost from ctenari where status='student' and platnost>now();
select * from ctenari where status='student' and platnost>now();
K celé tabulce ...
select * from ctenari;
můžeme přidat sloupec, vypočtený z jiných sloupců.
Funkce datediff() vrací rozdíl dat ve dnech:
select *,datediff(platnost,registrace) from ctenari;
Můžeme ho přejmenovat na něco kratšího:
select *,datediff(platnost,registrace)as dny from ctenari;
Pomocí funkcí můžeme formátovat výsledné zobrazení dat.
Funkce date_format() formátuje datum podle formátovacího řetězce:
select registrace,date_format(registrace,'%d') from ctenari;
select registrace,date_format(registrace,'%d %m') from ctenari;
select registrace,date_format(registrace,'%d%m') from ctenari;
select registrace, date_format(registrace,'%d%m') from ctenari;
select registrace,date_format(registrace,'%d% m') from ctenari;
select registrace,date_format(registrace,'%d %m %y') from ctenari;
select registrace,date_format(registrace,'%d %m %Y') from ctenari;
select registrace,date_format(registrace,'%d.%m.%Y') from ctenari;
select registrace,date_format(registrace,'%D %M %Y') from ctenari;
A s aliasem:
select registrace,date_format(registrace,'%d.%m.%Y')as datum from ctenari;
Pokud ve výsledku máme hodnoty, které se opakují ...
select status from ctenari;
... můžeme chtít, aby se vypsaly jen řádky, které se vzájemně liší:
select distinct status from ctenari;
select distinct platnost from ctenari;
Slovo DISTINCT znamená vyber odlišné (celé) řádky. Používá se jen za SELECT.
select distinct platnost,status from ctenari;
Chceme-li omezit výsledek na prvních několik řádků, použijeme LIMIT:
select * from ctenari limit 5;
select * from ctenari limit 10;
select * from ctenari limit 1;
To je výhodné na zkoušení příkazů u tabulek s velkým počtem řádků.
Řádky ve výsledku můžeme uspořádat podle sloupce:
select * from ctenari order by jmeno;
select * from ctenari order by status;
Nebo podle několika sloupců:
select * from ctenari order by status,jmeno;
Nejdřív se řadí podle statusu, pro stejné podle jména.
Pokud je sloupec číselný, tak se místo abecedního řazení řadí číselně:
select * from ctenari order by id;
Nebo podle data:
select * from ctenari order by registrace;
A kombinace data a abecedy:
select * from ctenari order by registrace,jmeno;
Pro sestupné řazení se použije DESC za názvem sloupce:
select * from ctenari order by jmeno desc;
Pro vzestupné se může použít ASC, ale může se vynechat, takže se nepoužívá.
select * from ctenari order by jmeno asc;
Kombinace sestupného a vzestupného řazení:
select * from ctenari order by registrace desc,jmeno;
Oba sloupce sestupně:
select * from ctenari order by registrace desc,jmeno desc;
Příklad nalezení maximálního data registrace. (Jde to efektivněji pomocí funkce max() - viz dále).
select registrace from ctenari order by registrace desc limit 1;
Agregační funkce provádějí výpočty přes řádky tabulky.
count(*) počítá počet řádků:
select count(*) from ctenari;
Součet hodnot ve sloupci id:
select sum(id) from ctenari;
Maximální hodnota ve sloupci:
select max(id) from ctenari;
Minimum:
select min(id) from ctenari;
Aritmetický průměr:
select avg(id) from ctenari;
Použití agregační funkce na vybraných řádcích (jen studenti):
select avg(id) from ctenari where status='student';
Výpočet aritmetického průměru dvěma způsoby:
select avg(id),sum(id)/count(*) from ctenari;
Řádky tabulky můžeme zařadit do skupin podle hodnoty některého sloupce.
Zde čtyři skupiny podle hodnoty statusu:
select status from ctenari order by status;
Tyto řádky můžeme sdružit do těchto skupin tak, že každá skupina bude zastoupená jen jedním řádkem.
K tomu souží GROUP BY:
select status from ctenari group by status;
Pro sloupce, jejichž řádky mají ve skupině různé hodnoty, musíme použít nějakou agregační funkci.
Součet ve sloupci id ve skupinách podle statusu:
select status,sum(id) from ctenari group by status;
Počet řádků ve skupinách podle statusu:
select status,count(*) from ctenari group by status;
Tento příkaz funguje, ale pro sloupce mimo status nedává smysl, protože v těchto sloupcích se objeví pro každou skupinu řádků se stejným statusem jedna náhodně vybraná hodnota ze skupiny (např. jedno jméno reprezentuje celou skupinu všech studentů, což je k ničemu):
select * from ctenari group by status;
Tento typ příkazu se používá často. Zjistí, kolik různých hodnot a jak často (četnost) se vyskytuje v daném sloupci:
select status,count(*) from ctenari group by status;
Pro názornost s aliasem:
select status,count(*)as `pocet řádků` from ctenari group by status;
V kombinaci s ORDER BY DESC dostaneme hodnoty seřazené podle jejich četnosti - nejčetnější napřed:
select status,count(*)as pocet from ctenari group by status order by pocet desc;
Tady je taky vidět, že řadit můžeme i podle vypočtených sloupců.
Řádky z GROUP BY jsou seřazené, jako by byl použitý navíc ORDER BY:
select status,count(*)as `pocet řádků` from ctenari group by status order by status;
DISTINCT vypadá podobně, ale nedělá to stejné. DISTINCT vyhazuje duplicitní řádky, GROUP BY řádky sdružuje podle hodnoty některých sloupců.
select distinct status from ctenari;
Toto je chybné směšování výpisu sloupce a agregační funkce.
select status,count(*)as `pocet řádků` from ctenari;
Je důležité, abyste pochopili, proč je toto chyba.
Když vypíšeme sloupec status, dostaneme ve výsledné tabulce 30 řádků:
select status from ctenari;
Když použijeme jen agregační funkci, dostaneme jeden řádek:
select count(*)as `pocet řádků` from ctenari;
V jedné výsledné tabulce nemůže být zároveň 30 řádků a jeden řádek. Promyslete!
select status,count(*)as `pocet řádků` from ctenari;
Jediná správná možnost, kdy můžeme za SELECT používat sloupce a zároveň agregační funkce, je s GROUP BY:
select status,count(*)as `pocet řádků` from ctenari group by status;
Tady dostaneme 4 řádky, protože status má 4 různé hodnoty. Pro každou hodnotu se použije agregační funkce na skupinu řádků, kterou tato hodnota sdružuje.
Všechna výše probíraná klíčová slova mohou být kombinovaná v jednom příkazu SELECT, protože jsou jeho součástí.
Toto je JEDEN příkaz zakončený středníkem:
select status,count(*)as pocet from ctenari where platnost>'2004-1-1' group by status order by pocet;
Důležité: Tato slova se musí v příkazu vyskytovat přesně v uvedeném pořadí, tedy SELECT, FROM, WHERE, GROUP BY, ORDER BY, LIMIT.
Kontrolní příklady
Použijte tabulku ctenari ze své databáze. Pokud vás už nebaví, zkoušejte si příkaz select na tabulkách z databáze VIK.