ARCHIV |
|||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
MySQL (30) - průběžné součtyJak vznést dotaz třeba na zůstatky na běžném účtu? A lze použít vícenásobných spojení téže tabulky i k aktualizaci dat?
Poslední ze "záhad" jazyka SQL, kterou bych se v tomto seriálu rád
zabýval, je vracení tzv. průběžných součtů (running totals). Ty si
můžete představit jako například zůstatky peněz na běžném účtu nebo
jako zůstatky zboží při pohybu ve skladu. Jak uvidíme, opět se něco
takového dá provést pomocí spojení tabulky se sebou samotnou. Dotaz na průběžné součtyVyjděme z příkladu se zůstatky na běžném účtu. Mějme například následující tabulku s pohyby na účtu a tato data: create table ucet (datum
date, castka decimal (10,2));
Sestavme nyní něco jako "výpis z účtu", tedy dotaz, který vrátí všechny pohyby i s jejich aktuálními zůstatky! Pokud zavzpomínáte na díl seriálu o číslování záznamů, bude i teď postup velmi podobný. Stačí šikovně spojit tabulku samu se sebou pomocí poddotazu: select ucet.datum,
ucet.castka, Všimněte si, že tohle je jeden z mála příkladů, kdy poddotaz logicky smí obsahovat klauzuli "sum" bez odpovídající kaluzule "group by". To proto, že součet bez definování skupiny sečte všechna data v daném sloupci dotazu, což je přesně to, co potřebujeme. Jak jsme již v tomto seriálu uvedli, drtivá většina poddotazů jde přepsat na spojení, tohle nevyjímaje. Takže, pokud jste spíše milovníky spojení, nebo pokud se ve vašem případě spojení prokáže být rychlejší, můžete to napsat takto: select ucet.datum,
ucet.castka, sum(vypocet.castka)
V tomto spojení se nevyskytují legrácky typu "klauzule SELECT v klauzuli JOIN" a podobné. Je to vlastně velmi čtivý dotaz, když se na něj podíváte. Jsou však oba uvedené dotazy v pořádku? Na první pohled jistě ano (i když se v reálné aplikaci jistě budou lišit rychlostí provádění). Co však, když v jeden den proběhne více operací najednou? Pojďme přidat následující řádek do tabulky! insert into ucet (datum,
castka) values ('20050110', -500);
Pokud si dotazy vyzkoušíte teď, zjistíte, že pro oba (teoreticky pro všechny) záznamy ze dne 10.1.2005 vracejí stejný mezisoučet. To je z hlediska, z něhož jsme dotazy psali naprosto logické, protože pro každý den zjišťují stav teprve po sečtení všech záznamů. Abychom to obešli, musíme jednotlivé záznamy od sebe nějak rozlišit a sčítat tyto rozlišené záznamy. V praxi to nejspíš nebude žádný velký problém, protože tabulka, jako je tato, bude mít téměř jistě nějaký klíč, třeba automaticky číslované řádky. Takže sem s ním! alter table ucet add id
int not null auto_increment primary key;
A přepišme naše dotazy tak, aby vzaly číslování řádků v úvahu. Ten první by mohl vypadat asi následovně: select ucet.datum,
ucet.castka,
a ten druhý takhle nějak: select ucet.datum,
ucet.castka, sum(vypocet.castka)
Tím, že se údaje rozliší, již nehrozí, že by se provedl mezisoučet
pro více než jeden řádek. Pozn.:Člověk někdy podlehne dojmu, že by stačilo odlišit od sebe jednotlivé záznamy například podle znaménka nebo podle částky, a že by se k tomu nemuselo volat na pomoc automatické číslování. Jenomže není to tak. Kdybychom odlišovali částky podle znaménka, seskupily by se nám součty pro všechny příjmy a výdaje za den, ale opět by nebyly rozlišeny jednotlivé pohyby. Kdybychom seskupovali podle částky, mohl by vzniknout stejný problém v případě, když by v jeden den přišly nebo odešly dvě platby ve stejné výši. A co akční dotazy?Mohla by vzniknout otázka, zda se dají triky nastíněné v několika předchozích dílech seriálu použít rovněž k úpravě dat, nejen k jejich vybírání. To je dobrá otázka. Například, daly by se využít zkušenosti z tohoto dílu k zapsání zůstatků na účtu do samostatného sloupce? Mějme tedy sloupec zachycující zůstatek: alter table ucet add
column zustatek decimal (10,2);
Do něj se dají celkem elegantně přepsat zůstatky pouhou úpravou výběrového dotazu na akční: update ucet join Přiznám se ale, že se tato technika moc často nevyužívá a že ji
příliš v lásce nemám. Důvod je velmi jednoduchý - v praxi to nemá moc
velký smysl. Kdybyste totiž chtěli na sloupec zůstatků spoléhat, musíte
jej přepočítat po každé změně tabulky - a to při větším množství
záznamů může docela trvat. Na druhou stranu se tato technika uchovávání výsledků výpočtů
používá celkem často u "statických" snímků dat, která pak slouží pro
nějaké analýzy či rozhodování. Tam to potom funguje zhruba tak, že:
To proto, že někdy je třeba vyhodnotit miliony záznamů - ostrý systém by to mohlo zatěžovat, ale malá nepřesnost způsobéná tím, že máme kopii "pouze včerejších" dat nemusí vadit.
Související články
Předchozí Celou kategorii (seriál) Další
MySQL (1) - pestrý svět databází
MySQL (2) - Instalujeme databázi MySQL MYSQL (3) Instalujeme MySQL podruhé MySQL (4) - něco terminologie MySQL (5) - tajuplné SQL MySQL (6) - Ukládáme řetězce MySQL (7) - hrátky s čísly MySQL (8) - Ukládání datumů MySQL (9) - Další datové typy MySQL (10) - tvorba databáze. Základy DDL MySQL (11) - vytváříme tabulky MySQL (12) - tipy k tvorbě tabulek MySQL (13) - Vkládáme data MySQL (14) - Upravujeme data MySQL (15) - Odstraňujeme data MySQL (16) - Tipy a triky k manipulaci s daty MySQL (17) - vybíráme data MySQL (18) - Filtrujeme data MySQL (19) - Řadíme data MySQL (20) - spojení více tabulek MySQL (21) - klauzule JOIN MySQL (22) - tipy a triky ke spojování tabulek MySQL (23) - relace 1:N a N:N MySQL (24) - Seskupujeme záznamy MySQL (25) - hrátky se seskupenými záznamy MySQL (26) - Poddotazy MySQL (27) - Složitější dotazy MySQL (28) - Dotazy pro pokročilé MySQL (29) - Vracení nejvyšších záznamů MySQL (31) - Indexy MySQL (32) - ještě k indexům MySQL (33) - Příkaz UNION MySQL (34) - větvení kódu a pivotní tabulky MySQL (35) - vestavěné funkce MySQL (36) - Regulární výrazy MySQL (37) - použití fulltextového vyhledávání MySQL (38) - Fulltext a praxe MySQL (39) - typy tabulek v MySQL MySQL (40) - další typy tabulek MySQL (41) - Transakce MySQL (42) - ještě k transakcím MySQL (43) - Uložené procedury MySQL (44) - parametry uložených procedur MySQL (45) - větvení kódu uložených procedur MySQL (46) - Triggery MySQL (47) - Triggery a praxe MySQL (48) - UDF MySQL (49) - pohledy MySQL (50) - Pohledy podruhé MySQL (51) - Metadata MySQL (52) - A co zálohování? MySQL (53) - SELECT INTO OUTFILE MySQL (54) - zálohování MySQL z webu MySQL (55) - zálohování MySQL z pohledu správce MySQL (56) - Obnova zálohovaných dat MySQL (57) - Ach, ta čeština MySQL (58) - čeština v praxi MySQL (59) - české řazení MySQL (60) - řádkový klient MySQL (61) - Oprávnění MySQL (62) - Oprávnění podruhé MySQL (63) - jemné nastavení práv MySQL (64) - nad dotazy čtenářů MySQL (65) - Ladíme server MySQL (66) - Ještě k ladění serveru MySQL - (67) MySQL (68) - Závěr MySQL (69) - Prepared Statements Předchozí Celou kategorii (seriál) Další
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera 12.11.2018 21:28 /Redakce Linuxsoft.cz 6.11.2018 2:04 /František Kučera 4.10.2018 21:30 /Ondřej Čečák 18.9.2018 23:30 /František Kučera 9.9.2018 14:15 /Redakce Linuxsoft.cz 12.8.2018 16:58 /František Kučera 16.7.2018 1:05 /František Kučera
Poslední diskuze
31.7.2023 14:13 /
Linda Graham 30.11.2022 9:32 /
Kyle McDermott 13.12.2018 10:57 /
Jan Mareš 2.12.2018 23:56 /
František Kučera 5.10.2018 17:12 /
Jakub Kuljovsky | |||
ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze |