ARCHIV |
|||||||||||||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
PostgreSQL (7) - Výběr dat z databázeData uložená v databázi je třeba nějakým relativně rozumným způsobem vybírat, filtrovaně a s možností využití relací na další data z jiných tabulek. Základy výběruVýběr dat z databáze je jednoduše realizován pomocí příkazu V praxi je znacne nevhodne vybirat z tabulky vsechna data, proto je vhodné vyjmenovat jen sloupce, které jsou třeba v dalším kroku zpracovaných dat. Toto souvisí především s rychlostí. V příštím díle bude vysvětleno urychlení výběrů pomocí indexace databáze a další zrychlení souvisí s pohledy (views), které budou vysvětleny v některém z pozdějších dílů. V tabulce, která byla vytvořena v minulém díle lze nyní, pokud v ní jsou nějaká data, provést několik výběrů. Níže je uvedena ukázka výběru všech položek a druhým dotazem výběr pouze jména a stavu uživatele. SELECT * FROM users; id | login | pwd | visible | hash ----+--------+------------------+---------+--------- 5 | petr | petr | t | 1 | jana | jana | f | 2 | petra | petra | f | 0 | vladka | 123 | f | (4 řádek) SELECT login, visible FROM users; login | visible --------+--------- petr | t jana | f petra | f vladka | f (4 řádek) Pomocí klíčového slova AS lze ovlivnit, pod jakým názvem budou navráceny sloupečky tabulky, prřípadně při spojování tabulek lze takto definovat zástupné jméno tabulek. Klauzule WHERESQL umožňuje zůžit výběr vět, které databáze vrátí k dalšímu zpracování. Ke zúžení slouží klauzule WHERE, za kterou se napíší podmínky, které je možné spojovat pomocí logických spojek. Pro tabulky, které byly vytvořeny pro tento text, lze výběrem Pomocí restrikce WHERE lze tabulky i spojovat do relací, ale k tomuto by měl sloužit především příkaz JOIN, který bude vysvětlen níže. V definované tabulce lze nyní provést výběr uživatelů, kteří mají parametr visible nastavený na "True" (PosgtreSQL jej vrací jako "t"), v dalším příkladě je výběr loginu a hesla uživatelů s parametrem id>=2 a v posledním příkladě je výběr vět, které splňují podmínky, kdy je jejich viditelnost nastavena na "False" a id>=2 a login bude vrácen jako jméno. SELECT * FROM users WHERE visible='t'; id | login | pwd | visible | hash ----+-------+------------------+---------+------------------ 5 | petr | petr | t | (1 řádka) SELECT login, pwd FROM users WHERE id>=2; login | pwd -------+---------------------- petr | petr petra | petra (2 řádek) SELECT login AS jmeno, pwd FROM users WHERE id>=2 AND visible='t'; jmeno | pwd -------+------------------- petr | petr (1 řádka) Klauzule ORDER BYPořadí vět ve výsledku lze ovlivnit pomocí přidání Klausule ORDER BY (seřadit dle), za kterou je uveden sloupeček podle kterého se má řadit, případně lze uvést směr řazení na sestupný (ASC), nebo sestupný (DESC), tato direktiva se udává za název sloupečku. Je možné nastavit řazení podle více sloupečků, v tom případě se neudává znovu klauzule order, ale jen název sloupečku, podle kterého se má řadit a případně direktivu směru. Výchozí směr je nastaven na vzestupný (ASC). Udání směru třídění se dáva za omezení vět ve výběru pomocí WHERE. SELECT id, login AS jmeno, pwd AS heslo FROM users WHERE id>=1 ORDER BY id DESC; id | jmeno | heslo ----+-------+----------------- 5 | petr | petr 2 | petra | petra 1 | jana | jana (3 řádek) Sdružování záznamů - GROUP BY a HAVINGKe sdružení řádků, podle stejných hodnot lze použít 2 funkce - GROUP BY a HAVING. Použití těchto funkcí s sebou přináší drobnou nesnáz, že je možné je použít jen v dotazech obsahujících agregační funkce (SUM, AVG, ...), které budou vysvětleny v dalším textu. Vhodným příkladem je užití k analýze návštěv WWW serveru, kdy záznamy jednotlivých návštěv jsou potřeba málokdy, ale většinou je vypovídající statistika kolik mávštěv přišlo ve které dny, případně dělení na hodiny. GROUP BY slouží jen ke sloučení řádků podle shodných hodnot ve sloupci/sloupcích, které jsou uvedeny za klíčovým spojením GROUP BY, pro sdružování je možné použít nejen názvy sloupců, ale i funkce ypracovávající hodnotu ze sloupce. Použití seskupování pomocí GROUP BY s sebou nese několik omezení v tom, co smí být ve výběru sloupců za příkazem SELECT:
Klauzule HAVING doplnuje sdružování o filtraci pomocí agregačních funkcí, tzn., že zahrnuty budou pouze ty souhrné řádky, které vyhoví podmínce v klauzyli HAVING. Pro další příklady je nutné definovat si další data do tabulky userdetails a vytvořit novou tabulku, kde budou jednotlivé objednávky (především kvůli detailům adresy, na kterou má být obědnávka po uzavření odeslána) a tabulka s detaily jednotlivých položek objednávky. SQL script, ve kterém je potřebný stav databáze naleznete ke stažení zde. Důvod k ukládání ceny produktu v momentě je ten, že změní-li se cena, je neslušné změnit cenu pro zákazníka (samozřejmě snížení je slušné promítnout a změnit všude, kde je v obědnávkách vyšší, při ukládání do ceníku, například triggerem). Následující příklady ukazují slučování pomocí GROUP BY a HAVING, první příklad ukazuje výsledek, je-li mimo groupovací podmínku, nebo pomocí agregační funkci některý ze sloupců. SELECT id_category, visible FROM products GROUP BY id_category; ERROR: column "products.visible" must appear in the GROUP BY clause or be used in an aggregate function SELECT id_category, visible FROM products GROUP BY id_category, visible; id_category | visible ------------+--------- 2 | t 3 | t SELECT id_category, visible, SUM(pieces*unitprice) AS hodnota_na_sklade FROM products GROUP BY id_category,visible HAVING SUM(pieces*unitprice)>=100; id_category | visible | hodnota_na_sklade ------------+---------+------------------- 2 | t | 150.00 3 | t | 2750.00 Spojování tabulekData z tabulek lze spojovat do větších celků pomocí relací (odtud název relační databáze). Do standardu ANSI-92 se dá použít spojování pomocí restriktoru WHERE, od vzniku této normy funguje pro spojování databází standardizovaný příkaz JOIN, který má několik modifikátorů ovlivňujících spojování tabulek. S použitím WHERE se lze setkat především starších programátorů a pro začátečníky může být o něco přehlednější (zejména při spojování více tabulek). Použití JOIN má větší možnosti ovlivnění způsobu spojení tabulek. Při spojování tabulek je nutné uvést názvy spojovaných tabulek a spojovací podmínky pro tyto tabulky. Při vyjmenovávání sloupečků je třeba předejít nejednoznačnostem v názvech (server tyto případy vyhodnotí jako chybu a dotaz není provede) buď pomocí názvu tabulky, za který se napíše název sloupce oddělený tečkou, nebo pomocí AS lze vytvořit zástupné jméno pro dotaz a použití je stejné jako u předchozího případu. Ve výběru se poté často používá klíčové slovo AS pro spřehlednění výstupních dat. Použití spojení pomocí WHERE i JOIN bude provedeno na tabulkách a datech připravených pro tento tutoriál. Při použití WHERE je syntaxe Spojování tabulek pomocí klauzule JOIN se vkládá za FROM místo názvu tabulky. Syntaxe je
Pro spojování 3 a více tabulek je třeba použít postupného spojení SELECT sloupecky FROM (tabulka1 LEFT JOIN tabulka2 ON vazeb_podminka) LEFT JOIN tabulka3 ON vazeb_podminka2. Přidání čtvrté a další tabulky se dělá obdobně. SELECT id, login, first_name, sure_name, email, visible FROM users, userdetails WHERE users.id=userdetails.id_user; ERROR: column reference "id" is ambiguous SELECT users.id AS id, login, first_name, surename, email, visible FROM users, userdetails WHERE users.id=userdetails.id_user; id | login | first_name | surename | email | visible ---+-------+------------+----------+----------------+--------- 5 | petr | Petr | Novák | petrik@neco.cz | t 5 | petr | Petr | Novák | novak@prvni.cz | t (2 řádek) SELECT t1.id AS id, login, first_name, surename, email, visible FROM users AS t1 LEFT OUTER JOIN userdetails AS t2 ON (t1.id=t2.id_user); id | login | first_name | surename | email | visible ---+--------+------------+----------+----------------+--------- 5 | petr | Petr | Novák | petrik@neco.cz | t 5 | petr | Petr | Novák | novak@prvni.cz | t 1 | jana | | | | f 2 | petra | | | | f 0 | vladka | | | | f 3 | root | | | | t (6 řádek) Join poskytuje na výstup vždy kartézský součin řádků přes odpovídající vazební podmínku. Pokud jsou v zůžení sloupců jen data, která jsou pro několik vět stejná, na výstupu je několik opticky stejných řádků, čehož lze docílit například vynecháním sloupce email v dotazu z předchozího příkladu. Tyto duplicity, nebo spíše multiplicity, se odstraňují doplněním DISTINCT, nebo DISTINCT BY za příkaz SELECT. DISTINCT jen "zruší" duplicitní záznamy, DISTINCT BY umožňuje vyjmenovat do, závorek, sloupečky, podle nichž se odstraní duplicity, nemusí to být sloupečky, která jsou ve výstupu. DISTINCT BY je rozšíření, které zavádí PgSQL na rámec normy. SQL92 definuje i příkaz DISTINCTROW, který sloučí pouze ty řádky ze spojení tabulek, které si odpovídají ve všech sloupcích. Spojení téže tabulkyTabulku lze spojit samu se sebou. Případ použití je získání seznamu, který je v jedné tabulce a věta obsahuje odkaz na větu, která je hierarchicky nad ní. V databázi, která je v tomto materiálu příkladová je to tabulka kategorií produktů. Toto spojení je pro začátečníky trochu obtížněji pochopitelné. SELECT DISTINCT t1.id AS id, login, first_name, surename, visible FROM users AS t1 RIGHT JOIN userdetails AS t2 ON (t1.id=t2.id_user); id | login | first_name | surename | visible ---+-------+------------+----------+--------- 5 | petr | Petr | Novák | t (1 řádka) SELECT DISTINCT ON (t2.email) t1.id AS id, login, first_name, surename, visible FROM users AS t1 RIGHT JOIN userdetails AS t2 ON (t1.id=t2.id_user); id | login | first_name | surename | visible ---+-------+------------+----------+--------- 5 | petr | Petr | Novák | t 5 | petr | Petr | Novák | t (2 řádek) SELECT DISTINCT t1.title, t1.description, t1.id, t1.id_parent FROM prodcategory AS t1 LEFT JOIN prodcategory AS t2 ON t1.id=t2.id_parent ORDER BY id_parent; title | description | id | id_parent --------------+---------------------------------------------------+----+----------- Linux | Linux distributions | 1 | 0 Slackware | Linuxová distribuce, která nemyslí | | | za uživatele při instalaci | 3 | 1 SLAX | Mini Live založená na Slackware | 4 | 3 Vector Linux | Linuxová distribuce založená na Slackware | 2 | 3 (4 řádek) V posledním příkladu stačí teoreticky nastavit pořáteční podmínku pro získání hierarchie kategorií pro určitý výrobek. Například má-li zákazník zájem o SLAX, vidí jeho zařazení pod Slackware a to zařazené pod Linux (Linux má uveden id_parent=0, tzn. že je top level kategorie). V praxi se vytvoření této cesty dělá pomocí scriptu. ZávěremV tomto díle bylo vysvětlená základní práce s dotazem SELECT při získávání dat. V příštím díle bude další práce s příkazem SELECT a složené SELECTy.
Související články
Předchozí Celou kategorii (seriál) Další
PostgreSQL (1) - Historie a pohledy jinam
PostgreSQL (2) - Proč PgSQL, data a relace PostgreSQL (3) - Instalace, základní administrace PostgreSQL (4) - Datové typy, vytvoření tabulek PostgreSQL (5) - Další datové typy a práce s časem i binarními řetězci PostgreSQL (6) - Uložení, aktualizace a mazání dat. PostgreSQL (8) - SELECT II. PostgreSQL (9) – SELECT III PostgreSQL (10) - SELECT IV PostgreSQL (11) - Výběr pomocí vzorků PostgreSQL 12 - urychlení výběrů PostgreSQL (13) - Na co se zapomnělo PostgreSQL (14) - omezení dat (Constraints) PostgreSQL (15) - Transakce PostgreSQL (16) - Zamykání PostgreSQL (17) - Datový typ pole PostgreSQL (18) - Datový typ pole II PostgreSQL (19) - Vlastní datové typy PostgreSQL (20) - Vlastní datové typy II PostgreSQL (21) - Spojování dotazů PostgreSQL (22) - Poddotazy PostgreSQL (23) - Optimalizujeme rychlost PostgreSQL (24) - Views (Pohledy) PostgreSQL (25) - Administrace skupin a uživatelů PostgreSQL (26) - Rozšiřujeme funkčnost 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 |