Dnes: 18. ledna 2018    | Registrace | Hledáme | Redakce | Info | Testy | Školení | Ocenění | Nápověda | Čtenář: nepřihlášen

Rychlé odkazy
  • Hlavní stránka
  • Seznam rubrik
  • Ankety
  • Editoriály
  • TOP 15
  • KONFERENCE 2008
  • KONFERENCE 2007
  • KONFERENCE 2006
  • KONFERENCE 2005
  • KONFERENCE 2004
  • Sborník
  • Testy
  • Virtuální školení
  • Personalizace


  • Hledáte práci?
    Hledáme redaktora - pojďte s námi tvořit Databázový svět!

    Vyhledávání

    Hledej
    na Databázovém světě!



    Rozšířené vyhledávání

    Rubriky
    Aktuality
    Bezpečnost
    Business
    Česká scéna
    Datové sklady
    Dokumentace
    Dotazovací jazyky
    Hardware
    Historie
    Komentáře
    Literatura
    Metodologie
    Nondb
    Open Source
    Poradna
    Produkty
    Případové studie
    Redakce
    Rozhovory
    Standardy
    Technologie
    Tipy - triky
    Tiskové zprávy
    Vývoj
    Vývojové nástroje
    Zajímavosti

    Co je to?
    Konkurenční přístup
    Situace, kdy k jednomu zdroji dat (nejčastěji stejným záznamům v tabulce) přistupuje současně více uživatelů. Jedním z úkolů vyspělého SŘBD je zajistit, aby nedošlo k porušení konzistence dat (například aby uživatel z tabulky četl vždy aktuální data).

    Akce
    Dynamická Datová Centra
    - na semináři se seznámíte s komplexním řešením a koncepcí Dynamických Datových Center od Fujitsu Siemens Computers se speciálním důrazem na řešení FlexFrame.

    Textová inzerce
    IBPhoenix - Vše o InterBase a Firebirdu.

    Smějete se rádi? - Pak je pro vás Vtipník to pravé!

    Prodejce reklamy - Hledáme schopného prodejce reklamního prostoru, možnost i externí spolupráce.

    Přihlášený čtenář
    Nepřihlášený čtenář

    O portálu
    Databázový svět
    ISSN: 1213-5933

    Web je optimalizován pro rozlišení 1024x768, nicméně kromě větších rozlišení podporujeme i 800x600. Podrobnosti najdete zde.

    Chcete-li mít kdykoliv možnost zkontrolovat obsah našeho portálu, můžete využít podporu rss. Podrobnosti najdete zde.
    Vyvíjíme databázový a informační systém XVII.


    [Metodologie] - V dalším – již sedmnáctém – pokračování našeho rozsáhlého seriálu o základních principech a o vývoji databázových a informačních systémů se podíváme na agregační funkce a řekneme si něco také o náhodném třídění v prostředí dotazovacího jazyka SQL. Dnes na vás tak čeká řada praktických příkladů.



    Pokud potřebujeme v rámci SQL dotazu omezit výstupní počet řádků nebo sloupců, máme k dispozici již v předchozích dílech probranou projekci a restrikci. Někdy nás ale nezajímá ani celkový přehled či vybraný detail, ale spíše celkové zhodnocení. Tím pak může být třeba získání minimální, průměrné nebo maximální hodnoty. Pro takový požadavek pak máme k dispozici shlukování neboli agregaci, což je postup, kdy nahrazujeme určitou skupinu řádků tabulky řádkem jediným. Předpisu pro výpočet hodnoty ve shluku říkáme agregační funkce. Následující tabulka klíčových slov nás seznamuje s potřebným názvoslovím pro uskutečnění požadovaného postupu agregace v SQL.


    Klíčová slova pro agregace

    Nejjednodušší situace při agregaci nastává, když nerozlišujeme jednotlivé řádky výchozí tabulky a ze všech řádků vytvoříme jeden agregát. Ten pak obsahuje jednotlivé hodnoty agregačních funkcí. Již byly uvedeny minimální, maximální a průměrné hodnoty, dále jsou v SQL k dispozici ještě agregační funkce pro součet a pro počet všech agregovaných hodnot. Ve většině případů je však výchozí situace pro výpočet složitější a my se pak snažíme vytvořit v rámci jedné tabulky více agregátů a v nich pak samostatně vyčíslit hodnoty agregačních funkcí.

    Začněme ale nejdříve s nejjednoduššími případy. Pokud jsou data v používané tabulce úplná a nechceme rozlišovat jednotlivé řádky, pak by mohlo vypadat použití agregačních funkcí následovně:

    SELECT COUNT(SLOUPEC),
           SUM(SLOUPEC), 
           AVG(SLOUPEC), 
           MIN(SLOUPEC), 
           MAX(SLOUPEC) 
      FROM TABULKA
    

    Výsledkem je zde tabulka o jednom řádku obsahující hodnoty agregačních funkcí. Po řadě obsahuje hodnotu počtu platných hodnot sloupce SLOUPEC, součtu, aritmetického průměru, minimální a maximální hodnotu. Při používání agregačních funkcí není nutné omezovat výpočty pouze na jeden sloupec. Agregační funkce jako svůj parametr přijme jakýkoliv výraz používající libovolný počet sloupců původní tabulky.

    SELECT COUNT(SLOUPEC1*SLOUPEC2) 
      FROM TABULKA
    

    Je důležité zmínit chování agregačních funkcí vůči nedefinovaným hodnotám NULL. Nedefinované hodnoty se totiž nezapočítávají do počtu, součtu, minima a maxima. Jedná se tedy o výjimku pravidla, že NULL způsobí v aritmetických výrazech nedefinovanou hodnotu výsledku. Výjimka výjimky je pak agregační funkce COUNT(*), která zjistí počet řádků, aniž by hleděla na nedefinovanost jejich obsahu.

    Pro vlastní seskupování údajů v příkazu SELECT využíváme klauzulí GROUP BY a HAVING. Pomocí první klauzule GROUP BY rozdělujeme záznamy databázové tabulky do skupin a samozřejmě její použití spojíme s některou z agregačních funkcí. Použijeme-li jeden sloupec tabulky jako klíč ke shlukování řádků do agregátů, uvedeme klíčové slovo GROUP BY a za ním název agregačního sloupce. Pro přehlednost a srozumitelnost se tento sloupec uvede v seznamu zobrazovaných hodnot na prvním místě, a potom se teprve uvede hodnota(y) agregační funkce. Dále může následovat třídění tohoto sloupce s využitím ORDER BY na konci SQL příkazu.

    SELECT popis projekce
      FROM tabulka
      WHERE podmínka restrikce
      GROUP BY klíč agregace
      ORDER BY klíč třídění
    

    Postupně jde tedy o povinný popis projekce následovaný datovým zdrojem, poté je na řadě nepovinný popis restrikce, nepovinný klíč k agregaci a nepovinné třídění podle obecně jiného klíče. Na tomto místě je opět dobré promyslet pořadí jednotlivých vykonávaných operací na SQL serveru. Začíná se výběrem tabulky, po kterém následuje restrikce, která nám často výrazně sníží počet řádků. Dále je na řadě agregace, jenž se už však zabývá jen vybranými řádky po restrikci a podle klíče nebo bez něj jsou sestaveny agregáty s využitím agregačních funkcí. Následuje třídění a teprve na konci je provedena projekce jednotlivých sloupců.

    TABULKA => 
      RESTRIKCE => 
        AGREGACE => 
          TŘÍDĚNÍ => 
            PROJEKCE
    

    Chceme-li použít jako klíč ke shlukování řádku do agregátů více sloupců tabulky, uvedeme zcela obvykle za klíčové slovo GROUP BY názvy příslušných sloupců oddělené čárkou. V podstatě popisujeme složený klíč pro agregaci.

    Pokud bychom chtěli po agregaci naplánovat ještě druhou restrikci, budeme používat vyhrazené slovo HAVING. Nepleťte si používání klauzulí WHERE a HAVING – klauzuli WHERE používáme k práci nad vstupními údaji, kdežto klauzuli HAVING nad již seskupenými údaji po použití klauzule GROUP BY. Samozřejmě lze obě klauzule kombinovat i v rámci jednoho příkazu SELECT.

      SELECT popis projekce
      FROM tabulka
      WHERE podmínka restrikce řádků
      GROUP BY klíč agregace
      HAVING podmínka restrikce skupiny
      ORDER BY klíč třídění
    

    Pořadí kroků SQL serveru by potom vypadalo následovně:

    TABULKA => 
      RESTRIKCE RADKU => 
        AGREGACE =>
          RESTRIKCE SKUPIN => 
            TRIDENI SKUPIN => 
              PROJEKCE
    


    Pracovní tabulka nákupy

    S použitím tabulky vytvoříme novou tabulku se sloupci POCET_POLOZEK a POCET_DRUHU a budeme počítat:

    SELECT COUNT(*) POCET_POLOZEK,
           COUNT(DISTINCT CO) POCET_DRUHU
      FROM NAKUPY
    

    Dále vytvoříme denní přehled výdajů za potraviny:

    SELECT DEN, 
           SUM(PLACENO) VYDAJE
      FROM NAKUPY
      GROUP BY DEN
      ORDER BY DEN

    Dále sestavíme přehled o minimální, průměrné a maximální jednotkové ceně za každou potravinu:

    SELECT CO, 
           COUNT(*) POCET_HODNOT,
           MIN(PLACENO/KOLIK) MINIMALNI,
           AVG(PLACENO/KOLIK) PRUMERNA,
           MAX(PLACENO/KOLIK) MAXIMALNI
      FROM NAKUPY
      GROUP BY CO
      ORDER BY CO
    

    Jako poslední příklad na agregační funkce si zkusíme "spojit" několik požadavků dohromady. Všimněte si použití oddělené restrikce řádků a restrikce skupin uskutečněné až po provedené agregaci. Bude nás zajímat výpis výdajů za den v týdnu, přičemž nebudeme započítávat mléko, nezajímají nás dny pátek, sobota a neděle a ze zbylých součtů nás budou zajímat jen ceny přesahující 80 Kč.

    SELECT DEN, 
           SUM(PLACENO) VYDAJE
      FROM NAKUPY
      WHERE CO != 'MLEKO' AND 
            DEN NOT IN ('PATEK','SOBOTA','NEDELE')
      GROUP BY DEN
      HAVING SUM(PLACENO)>80
      ORDER BY DEN
    

    Náhodné "třídění" údajů
    Projdete-li si alespoň myšlenkově dotazy, které jsme používali v předchozích dílech, možná vás ve spojení s touto částí dnešního pokračování napadne, že třídění získaných výsledků jsme brali jako automatickou záležitost. Jedná se přitom o část zpracování, která je velice důležitá pro výslednou srozumitelnost získaných výsledků. Zkusíme si však dnes i opačný problém – náhodné uspořádání výsledků. Zdánlivě jednoduchá věc, ale dovede potrápit.

    Nejdříve si však zopakujme "správné" třídění. Při požadavku utřídění výsledků máme většinou na mysli třídění podle abecedy nebo čísla popř. data apod. Pro tuto součást dotazu je vyhrazena část uvozená klauzulí ORDER BY. Při běžných pravidlech zápisu SQL příkazu SELECT je použita na konci.

    SELECT popis projekce
      FROM tabulka
      WHERE podmínka restrikce řádků
      GROUP BY klíč agregace
      HAVING podmínka restrikce skupiny
      ORDER BY klíč třídění
    

    Požadujeme-li vzestupné třídění (tj. od nejmenší hodnoty po největší, u abecedy od A k Z) můžeme využít klauzuli ASC. Slůvko "můžeme" zde naznačuje, že se jedná o nastavení výchozí (přednastavené). Pro sestupné třídění využíváme klauzuli DESC, která je již ovšem pro správné provedení povinná. Abychom pro ukázku předvedli alespoň jedno použití, setřídíme v minulých dílech již využívanou tabulku země. Pro třídění lze využít i přezdívky (aliasu):

    Konzole MySQL
    Konzole MySQL

    Jednotlivé způsoby třídění (vzestupně, sestupně) lze samozřejmě dle potřeby s výhodami kombinovat. Například pro výpis seřazených záznamů podle příslušnosti kontinentů (abeceda) a dále u jednotlivých skupin kontinentů jsou seřazeny jednotlivé záznamy podle aktuálního počtu obyvatel. Ostatně podívejme se na to:

    Konzole MySQL
    Konzole MySQL

    Nyní se v problematice posuňme k myšlence náhodného utřídění výsledků. Pokud bychom chtěli nejdříve stanovit možnou oblast použití "náhody", napadne nás třeba sestavení testovacích sad otázek, rozlosování týmů pro budoucí turnaj, rozpis kontrol práce zaměstnanců apod. Pro vlastní generování náhody (zní to strašně, že?) v prostředí MySQL můžeme využít funkce RAND() a RAND(inicializační hodnota) . Obě tyto funkce generují pseudonáhodná čísla s plovoucí čárkou v rozmezí intervalu 0–1. Při použití vstupního parametru zadáváme základní inicializační hodnotu generátoru pseudonáhodných čísel. V druhém případě je tedy vhodné při opakovaném použití dodávat na vstupu různá čísla, jinak bude generována stejná posloupnost hodnot.

    SELECT NAZEV AS STAT 
      FROM ZEME 
      ORDER BY RAND()
    

    Použitím funkce RAND() se nám podaří poměrně jednoduše dosáhnout náhodného uspořádání výsledků. O náhodnosti se asi nejlépe přesvědčíme opakovaným použitím téhož příkazu a porovnáním získaných výsledků. Pokud bychom chtěli vědět přesněji, s jakými generovanými hodnotami si to vlastně "zahráváme", necháme si jejich výpis taktéž připojit do výsledného zobrazení výsledků, třeba i s lépe sledovatelným identifikačním číslem záznamu.

    SELECT NAZEV AS STAT, 
           CISLO, 
           RAND() 
      FROM ZEME 
      ORDER BY RAND()
    

    Konzole MySQL
    Konzole MySQL

    Potřebujeme-li z nějakého důvodu využít tvar funkce RAND() s inicializací generátoru pseudonáhodných čísel je důležité nastavit pro opakované dotazy odlišnou inicializační hodnotu pro získání odlišných výsledků. Pro přesné pochopení "odlišnosti" inicializačních čísel, můžete vyzkoušet generování náhodné hodnoty postupně pomocí těchto dotazů.

    SELECT RAND(10) ...
    
    SELECT RAND(100) ...
    
    SELECT RAND(1000000000000) ...
    

    První dva výsledky budou odlišné jen mizivě. Třetí výsledek je konečně "jinou" hodnotou. Poskytneme-li totiž generátoru náhodných čísel jako inicializační základ čísla málo se lišící, dostaneme jako výsledek hodnoty na náhodu také příliš blízké. Pokud už tedy potřebujeme dostat různé hodnoty, nejspíše využijeme služeb neustále se měnícího času.

    Související články:
    Vyvíjíme databázový a informační systém XXV. (28.12.2004)
    Vyvíjíme databázový a informační systém XXIV. (27.12.2004)
    Vyvíjíme databázový a informační systém XXIII. (16.12.2004)
    Vyvíjíme databázový a informační systém XXII. (07.12.2004)
    Vyvíjíme databázový a informační systém XXI. (16.11.2004)
    Vyvíjíme databázový a informační systém XX. (03.11.2004)
    Vyvíjíme databázový a informační systém XIX. (25.10.2004)
    Vyvíjíme databázový a informační systém XVIII. (13.10.2004)
    Vyvíjíme databázový a informační systém XVI. (21.09.2004)
    Vyvíjíme databázový a informační systém XV. (13.09.2004)
    Vyvíjíme databázový a informační systém XIV. (25.08.2004)
    Vyvíjíme databázový a informační systém XIII. (18.08.2004)
    Vyvíjíme databázový a informační systém XII. (02.08.2004)
    Vyvíjíme databázový a informační systém XI. (14.07.2004)
    Vyvíjíme databázový a informační systém X. (07.07.2004)
    Vyvíjíme databázový a informační systém IX. (01.07.2004)
    Vyvíjíme databázový a informační systém VIII. (23.06.2004)
    Vyvíjíme databázový a informační systém VII. (16.06.2004)
    Vyvíjíme databázový a informační systém VI. (09.06.2004)
    Vyvíjíme databázový a informační systém V. (02.06.2004)
    Vyvíjíme databázový a informační systém IV. (26.05.2004)
    Vyvíjíme databázový a informační systém III. (19.05.2004)
    Vyvíjíme databázový a informační systém II. (12.05.2004)
    Vyvíjíme databázový a informační systém I. (05.05.2004)

    ( Celý článek! | Autor: Martin Pokorný | Počet komentářů: 1 | Přidat komentář | Informační e-mailVytisknout článek )

    Vyhledávání
     

    Anketa
    Kolik ročně utratíte za dovolené?

    Nic 
     (1548 hl.)
    Do 1 000,- Kč 
     (1068 hl.)
    Do 10 000,- Kč 
     (999 hl.)
    Do 25 000,- Kč 
     (1378 hl.)
    Do 50 000,- Kč 
     (1016 hl.)
    Do 75 000,- Kč 
     (1178 hl.)
    Více než 75 000,- Kč 
     (1019 hl.)

    Celkem hlasovalo: 8206


    Poslední komentáře
    frontierd@126.com
    frontierd@126.com
    frontierd@126.com
    c
    http://www.coachoutl

    Newsletter
    Přihlaste si nezávazně - i bez registrace - odběr informačního newsletteru. Podrobné informace najdete zde.

    Emailová adresa:


    Kalendář
    <<  Leden  >>
    PoÚtStČtSoNe
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    

    Redakci připojuje


    Nejčtenější

    Databáze je prázdná!


    Nejvíce komentářů

    Databáze je prázdná!


    Reklama






    Nenechte si ujít články na dalších webech




    Na této stránce použité názvy programových produktů, firem apod. mohou být ochrannými známkami
    nebo registrovanými ochrannými známkami příslušných vlastníků.

    Databázový svět | dfKlub - digitální fotografie | Vtipník - vtipy přímo k Vám | Reminder - přestaňte zapomínat | Databázový svět

    Copyright (c) 2004 AVRE Publishing, spol. s r.o. Všechna práva vyhrazena