1. cvičení - rychlokurz

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

  1. Zjistěte počet čtenářů s platným členstvím k zadanému datu, třeba dnešku.
  2. Podle zadaného ID vypište jméno čtenáře a jeho status.
  3. Vypište seznam studentů seřazený abecedně.
  4. Vypište nejčetnější status čtenáře.

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.