LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> MySQL (34) - větvení kódu a pivotní tabulky

Znát podmíněné příkazy v MySQL může přijít vhod. Zejména na šílenosti typu pivotních tabulek a souhrnů. Což je dnešní téma seriálu MySQL.

19.8.2005 07:00 | Petr Zajíc | Články autora | přečteno 24130×

Situaci, kdy je potřeba provést nebo neprovést určitý úsek kódu v závislosti na splnění podmínky budete znát spíše z "klasických" programovacích jazyků. Jak ale uvidíme v dnešním díle seriálu o MySQL, jde to použít i v dotazech, a leckdy to má docela opodstatnění. Tak či tak, znát příkazy pro rozbočení kódu může být docela užitečné.

Větvení kódu v MySQL

Především je dobře si uvědomit, kdy se asi budou podobné hrátky s příkazy používat. Bude to v situacích, kde chceme vrátit (či změnit) data v závislosti na nějaké podmínce - nejčastěji v závislosti na datech jiných. Tak nám například jeden a tentýž dotaz může vrátit různá data na základě toho, jaká hodnota je uvedena ve sloupci a podobně. Pro některé typy dotazů je to nepostradatelné.

Příkaz IF

Příkaz IF je obdobou ternárního operátoru, jaký známe z většiny programovacích jazyků. Obsahuje tři části. Vyhodnotí se podmínka (1. část), jestliže je splněna, je vrácen jako výsledek výraz ve druhé části, jestliže ne je vrácen výraz ve třetí části. Mohlo by to vypadat nějak takto:

select jmeno, if (plat>15000,'nadprůměrný','podprůměrný') as plat from pracovnik

V případě jednoduchých rozhodování tento příkaz přes svoji úspornost jistě postačí. Může to ušetřit následné zpracování "řádek po řádku" v nějaké aplikaci, která bude tato data konzumovat. Samozřejmě, že podobnou konstrukci lze použít nejen v příkazu SELECT, ale třeba i v UPDATE.

Příkaz IFNULL

Zvláštním případem jednoduchého větvení budiž příkaz IFNULL. Ten má dva argumenty. Pokud ten první je rovnen hodnotě NULL, je vrácen druhý, jinak první. To se často hodí v případě, kdy sloupec smí obsahovat hodnoty NULL, ale my je v daném případě chceme nahradit nějakou jinou hodnotou. Kdyby směl sloupec plat obsahovat hodnoty NULL a my je chtěli nahradit nulou, šli bychom na to takto:

SELECT jmeno, IFNULL(plat,0) AS plat FROM pracovnik

Což je mimochodem rovnocenné zápisu

SELECT jmeno, IF(plat is null,0,plat) AS plat FROM pracovnik

Co k tomu dodat? Snad jen že existuje i funkce NULLIF, která funguje poněkud jinak a v praxi se téměř nepoužívá. Její popis byste našli v manuálu k MySQL. Ano, a ještě to, že některé DBMS mají funkci IFNULL nazvánu ISNULL, takže se mi to neustále plete.

Příkaz CASE

Case umí větvit kód na více částí a navíc má dvě syntaktické formy. Tudíž je nejsložitější z uvedených příkazů pro větvení. Zase toho ale nejvíc umí a poměrně často se používá. První forma je tzv. "rozhodovací" a vypadá takto:

SELECT JMENO,
CASE
  WHEN PLAT < 12000 THEN 'málo'
  WHEN PLAT > 12000 AND PLAT < 15000 THEN 'středně'
  WHEN PLAT > 15000 THEN 'ujde to'
END as PLAT
FROM pracovnik

Druhá, "prohledávací" pak vypadá nějak takhle

SELECT JMENO,
CASE STATUS
  WHEN 1 THEN 'zaměstnán'
  WHEN 2 THEN 'propuštěn'
  WHEN 3 THEN 've zkušební době'
  ELSE 'neznámý'
END
from pracovnik

Jak vidíte, její typické použití je právě ve spojení s "překladem" jednoduchých "stavových" informací na jejich srozumitelné protějšky.

Praxe

Pro použití těchto konstrukcí v praxi bych měl několik tipů, které se Vám možná budou hodit. Především - s nástroji pro větvení kódu je třeba zacházet opatrně. Mějte na paměti, že použití mnoha (zejména vnořených) konstrukcí CASE nebo IF může kód poněkud znepřehlednit. V příkladech "prohledávacího" typu CASE je navíc možné stavové informace uložit do samostatné tabulky a potom to spojit pomocí relace - odpadá tak nutnost úpravy v kódu v případě, kdy by se přidávala nová větev (nový stav).

Ještě jeden tip z praxe - kdekoli je to možné, hodí se zdrojové kódy SQL obsahující větvení formátovat, aby byly hezky čitelné. Sám jsem se o to v příkladech výše snažil.

Pivotní tabulky

Pomocí příkazu CASE se lehce dají vytvořit pivotní tabulky, tedy takové pohledy na data, které shrnují "řádkové" výsledky do sloupců. Než bych to dlouhosáhle vysvětloval, raději to předvedu na příkladu. Mějme tabulku vystavených faktur

create table faktury (datum date, castka decimal(10,2));
insert into faktury (datum, castka) values('20040101', 2200);
insert into faktury (datum, castka) values('20040201', 2600);
insert into faktury (datum, castka) values('20040301', 2500);
insert into faktury (datum, castka) values('20040501', 3800);
insert into faktury (datum, castka) values('20040701', 4200);
insert into faktury (datum, castka) values('20040806', 2100);
insert into faktury (datum, castka) values('20040901', 2300);
insert into faktury (datum, castka) values('20040906', 2800);
insert into faktury (datum, castka) values('20041001', 3100);
insert into faktury (datum, castka) values('20050101', 4000);
insert into faktury (datum, castka) values('20050201', 5000);
insert into faktury (datum, castka) values('20050301', 5500);
insert into faktury (datum, castka) values('20050501', 4200);
insert into faktury (datum, castka) values('20050701', 4800);
insert into faktury (datum, castka) values('20050806', 6100);
insert into faktury (datum, castka) values('20050901', 3200);
insert into faktury (datum, castka) values('20050906', 2200);
insert into faktury (datum, castka) values('20051001', 8500);

a šéfa. Ten jednoho krásného dne přijde s tím, že chce výsledky ve formě tabulky, kde každý řádek bude obsahovat data za jeden rok a sloupce budou obsahovat součty pohybů za jednotlivé měsíce. Tento požadavek se v mnoha obměnách opakuje v nejrůznějších aplikacích, takže následující postup se docela vylatí znát. Dotaz bude vypadat nějak takto:

select rok,
sum(case when mesic=1 then castka else 0 end) as 'leden',
sum(case when mesic=2 then castka else 0 end) as 'únor',
sum(case when mesic=3 then castka else 0 end) as 'březen',
sum(case when mesic=4 then castka else 0 end) as 'duben',
sum(case when mesic=5 then castka else 0 end) as 'květen',
sum(case when mesic=6 then castka else 0 end) as 'červen',
sum(case when mesic=7 then castka else 0 end) as 'červenec',
sum(case when mesic=8 then castka else 0 end) as 'srpen',
sum(case when mesic=9 then castka else 0 end) as 'září',
sum(case when mesic=10 then castka else 0 end) as 'říjen',
sum(case when mesic=11 then castka else 0 end) as 'listopad',
sum(case when mesic=12 then castka else 0 end) as 'prosinec'
from
(
select year(datum) as rok, month(datum) as mesic, sum(castka) as castka
from faktury group by year(datum), month(datum)
) as soucty
group by rok

Všimněte si, že data za jednotlivé měsíce jsou nejprve sloučena v poddotazu, a ten je ve "vnějším" dotazu použit jako zdroj. Výhoda tohoto přístupu je jasná - dotaz seskupí data pro libovolný počet let a navíc v jednom měsíci může být libovolný počet pohybů (včetně žádného). Jen je ten kód trochu nudný na psaní.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

16.7.2018 1:05 /František Kučera

Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.


Přidat komentář

18.6.2018 0:43 /František Kučera
Červnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 21. 6. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: F-Droid, aneb svobodný software do vašeho mobilu. Kromě toho budou k vidění i vývojové desky HiFive1 se svobodným/otevřeným čipem RISC-V.
Přidat komentář

23.5.2018 20:55 /Ondřej Čečák
Od pátku 25.5. proběhne na Fakultě informačních technologií ČVUT v Praze openSUSE Conference. Můžete se těšit na spostu zajímavých přednášek, workshopů a také na Release Party nového openSUSE leap 15.0. V na stejném místě proběhne v sobotu 26.5. i seminář o bezpečnosti CryptoFest.
Přidat komentář

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

14.5.2018 7:28 /František Kučera
Květnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 17. 5. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: Audio – zvuk v GNU/Linuxu.
Přidat komentář

7.5.2018 16:20 /František Kučera
Na stránkách spolku OpenAlt vyšla fotoreportáž Pražské srazy 2017 dokumentující srazy za uplynulý rok. Květnový pražský sraz na téma audio se bude konat 17. 5. 2018 (místo a čas ještě upřesníme).
Přidat komentář

17.4.2018 0:46 /František Kučera
Dubnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 4. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tématem tohoto srazu bude OpenStreetMap (OSM) aneb svobodné mapy.
Přidat komentář

16.3.2018 22:01 /František Kučera
Kulatý OpenAlt sraz v Praze oslavíme klasicky: u limonády a piva! Přijďte si posedět, dát si dobré jídlo a vybrat z mnoha piv do restaurace Kulový blesk, který najdete v centru Prahy nedaleko metra I. P. Pavlova na adrese Sokolská 13, Praha 2. Sraz se koná ve čtvrtek 22. března a začínáme v 18:00. Heslo: OpenAlt. Vezměte s sebou svoje hračky! Uvítáme, když si s sebou na sraz vezmete svoje oblíbené hračky. Jestli máte nějaký drobný projekt postavený na Arduinu, nějakou zajímavou elektronickou součástku, či třeba i pěkný úlovek z crowdfundingové akce, neváhejte. Oslníte ostatní a o zábavu bude postaráno.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

16.1.2018 1:08 / Ivan Pittner
verejna ip od o2 ubuntu

15.1.2018 17:26 / Mira Harvalik
Re: Jak udělat HTML/Javascript swiping gallery do mobilu?

30.12.2017 20:16 / Michal Knoll
odmocnina

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze