7. díl - PostgreSQL - Dotazy přes více tabulek (JOIN)

PostgreSQL PostgreSQL - Dotazy přes více tabulek (JOIN)

V minulém dílu seriálu tutoriálů o PostgreSQL databázi jsme si ukázali datové typy a vysvětlili hodnotu NULL. Dnes si vytvoříme jednoduchý redakční systém, který může připomínat ten zde na ITnetwork. Ukážeme si dotazování přes více tabulek.

Konceptuální model

V následujících dílech si tedy v databázi vytvoříme takový zjednodušený ITnetwork. Pobavme se nejprve o tom, jak to bude vypadat. Dnes stihneme pochopitelně jen malou část. Protože obrázek někdy řekne více, než tisíc slov, začněme právě jím.

Databázový model redakčního systému

Co vidíte je tzv. konceptuální model. Je vytvořený pomocí notace (grafického jazyka) UML a v praxi se takovéto diagramy velmi často tvoří předtím, než začneme psát nějaký kód. Dobře si tak nejprve rozmyslíme, co že to vlastně chceme udělat.

Vidíme, že v systému figuruje uživatel, který může psát komentáře a články. Články spadají do sekcí. Jedná se tedy o databázi takového velmi jednoduchého redakčního systému, který si díky ITnetwork jistě dokážete představit.

Příprava tabulek a dat

Dnes se zaměříme na dotazy přes více tabulek. Pojďme si nejprve nějaké tabulky vytvořit. Bohatě nám budou stačit uživatelé a články.

Uživatelé

Protože uživatel bude vypadat trochu jinak, než nám vypadal doteď, založíme si tabulku uzivatel znovu. Tu současnou tedy dropneme:

DROP TABLE uzivatel;

Následně vytvoříme tabulku novou. Uživatel zde bude mít (kromě id) přezdívku, email a heslo:

CREATE TABLE uzivatel (
        uzivatel_id serial,
        prezdivka varchar(155),
        email varchar(155),
        heslo varchar(255),
        PRIMARY KEY (uzivatel_id)
);

Všimněte si, že používám datový typ VARCHAR (n). Je to to alias pro CHARACTER VARYING(n). Záleží na vás, co budete psát. Jedná se ten samý datový typ.

Rovnou si vložíme nějaké uživatele:

INSERT INTO uzivatel (prezdivka, email, heslo) VALUES
('Míša', 'misaslavikova@gmail.com', 'dGg#@$DetA53d'),
('David', 'capkadavid@seznam.cz', '$#fdfgfHBKBKS'),
('Denny', 'denny@hotmail.com', 'Jmls_aSW2RFss'),
('Ema', 'ema@centrum.cz', 'fw8QT32qmcsld');

Články

Článek bude propojen s uživatelem, který ho napsal, tedy s jeho autorem. Tabulky propojíme tak, že do tabulky clanek přidáme sloupec s id autora. Tam bude hodnota id uživatele (tedy primární klíč z tabulky uzivatel), který článek napsal.

Hovoříme o vazbě 1:N (1 uživatel má N (několik) článků a každý článek patří právě jednomu uživateli). Část (zde článek) má vždy uložené id celku (zde uživatel) kam patří.

Článek bude obsahovat (opět kromě svého id) id autora, krátký popis, url, klíčová slova, titulek, obsah a datum publikace. Založme si tabulku clanek:

CREATE TABLE clanek (
        clanky_id serial,
        autor_id integer,
        popis varchar(155),
        url varchar(155),
        klicova_slova varchar(155),
        titulek varchar(155),
        obsah text,
        publikovano timestamp,
        PRIMARY KEY (clanky_id)
);

Za povšimnutí stojí asi jen použití typu TEXT pro text článku.

Dále přidáme články a k nim přiřadíme uživatele jako autory. Vzal jsem 4 články zde z ITnetwork, které jsem značně zkrátil a zjednodušil. Dotaz bude následující:

INSERT INTO clanek (autor_id, popis, url, klicova_slova, titulek, obsah, publikovano) VALUES
(1, 'Co je to algoritmus? Pokud to nevíte, přečtěte si tento článek.', 'co-je-to-algoritmus', 'algoritmus, co je to, vysvětlení', 'Algoritmus', 'Když se bavíme o algoritmech, pojďme se tedy shodnout na tom, co ten algoritmus vůbec je. Jednoduše řečeno, algoritmus je návod k řešení nějakého problému. Když se na to podíváme z lidského pohledu, algoritmus by mohl být třeba návod, jak ráno vstát. I když to zní jednoduše, je to docela problém. Počítače jsou totiž stroje a ty nemyslí. Musíme tedy dopodrobna popsat všechny kroky algoritmu. Tím se dostáváme k první vlastnosti algoritmu - musí být elementární (skládat se z konečného počtu jednoduchých a snadno srozumitelných kroků, tedy příkazů). "Vstaň z postele" určitě není algoritmus. "Otevři oči, sundej peřinu, posaň se, dej nohy na zem a stoupni si" - to už zní docela podrobně a jednalo by se tedy o pravý algoritmus. My se však budeme pohybovat v IT, takže budeme řešit problémy jako seřaď prvky podle velikosti nebo vyhledej prvek podle jeho obsahu. To jsou totiž 2 základní úlohy, které počítače dělají nejčastěji a které je potřeba dokonale promýšlet a optimalizovat, aby trvaly co nejkratší dobu. Z dalších příkladů algoritmů mě napadá třeba vyřeš kvadratickou rovnici nebo vyřeš sudoku.', '2012-3-21'),
(2, 'Bakterie jsou obdoba buněčného automatu v kombinaci s hrou.', 'bakterie-bunecny-automat', 'bakterie, automat, algoritmus', 'Bakterie', 'Bakterie jsou obdoba buněčného automatu, který vymyslel britský matematik John Horton Conway v roce 1970. Celou tuto hru řídí čtyři jednoduchá pravidla:/n/n
1. Živá bakterie s méně, než dvěma živými sousedy umírá./n
2. Živá bakterie s více, než třemi živými sousedy umírá na přemnožení./n
3. Živá bakterie s dvoumi nebo třemi sousedy přežívá beze změny do další generace./n
4. Mrtvá bakterie, s přesně třemi živými sousedy, opět ožívá./n
Tyto zdánlivě naprosto primitivní pravidla dokáží za správného počátečního rozmístění bakterií vytvořit pochodující skupinky, shluky "vystřelující" pochodující pětice, překvapivě složité souměrné exploze, oscilátory (periodicky kmitající skupinky), či nekonečnou podívanou na to, jak složité a dokonalé obrazce dokáží tyto dvě podmínky vytvořit. Celý program je koncipován jako hra, máte za úkol vytvořit co nejdéle žijící kolonii. <a href="soubory/bakterie.zip" ', '2012-2-14'),
(3, 'Cheese Mouse je oddechová plošinovka.', 'cheese-mouse-oddechova-plosinovka', 'myš, sýr, hra', 'Cheese Mouse', 'Cheese mouse je plošinovka s "horkou ostrovní atmosférou", kde ovládáte myš a musíte se dostat k sýru. V tom vám ale brání nejrůznější nástrahy a nepřatelé jako hadi, krysy, pirane, ale i roboti, mumie a nejrůznější havěť. Hru s několika petrobarevnými světy jsem dělal ještě na základní škole s Veisenem a může se pochlubit 2. místem v Bonusweb game competition, kde vyhrála 5.000 Kč. Vznikala v Game makeru o letních prázdninách, ještě v bezstarostném dětství, což značně ovlivnilo její grafickou stránku. Rád si ji občas zahraji na odreagování a zlepšní nálady. <a href="soubory/cheesemouse.zip" />', '2004-6-22'),
(2, 'Pacman je remake kultovní hry.', 'pacman-remake', 'pacman, remake, pampuch, hra, zdarma', 'Pacman', 'Jedná se o naprosto základní verzi této hry s editorem levelů, takže si můžete vytvořit svá vlastní kola. Postupem času ji hodlám ještě trochu upravit a přidat nějaké nové prvky, fullscreen a lepší grafiku. Engine hry bude také základem mého nového projektu Geckon man, který je zatím ve fázi psaní scénáře. <a href="soubory/pacman.zip" />', '2011-6-3');

Dotazy přes více tabulek

Nyní máme v databázi články a k nim přiřazené uživatele. Pojďme si udělat dotaz přes tyto 2 tabulky, získejme články a k nim připojme přezdívky jejich uživatelů. Slovo připojme jsem nepoužil náhodou, příkaz pro spojení 2 tabulek se totiž jmenuje JOIN. Napišme si dotaz a poté si ho vysvětleme. Dotazy již budeme psát na více řádků, abychom se v tom vyznali.

SELECT titulek, prezdivka
FROM clanek
JOIN uzivatel ON autor_id = uzivatel_id
ORDER BY prezdivka;

Výsledek:

Pacman          David
Bakterie        David
Cheese Mouse    Denny
Algoritmus      Míša

Na prvním řádku příkazu SELECT pracujeme se sloupci úplně stejně, jako kdyby byly v jedné tabulce, jednoduše vyjmenujeme, co nás zajímá. Jelikož vybíráme články a k nim připojujeme uživatele, budeme vybírat z tabulky clanky. Připojení dat z jiné tabulky uděláme pomocí příkazu JOIN, kde uvedeme tabulku, kterou připojujeme, a poté klauzuli ON. Klauzule ON je podobná jako WHERE, jen platí pro připojovanou tabulku a ne pro tu, ze které primárně vybíráme. V podmínce uvedeme, aby se ke každému článku připojil ten uživatel, jehož uzivatele_id je uvedeno ve sloupci autor_id. Výsledek jsme seřadili podle přezdívky uživatelů. Kdybychom chtěli jen nějaké články, normálně bychom před ORDER BY uvedli ještě WHERE, jak jsme zvyklí.

Dotaz lze napsat i následujícím způsobem, kdy před název sloupce, podle kterého tabulky spojujeme, uvedeme i název tabulky.

SELECT titulek, prezdivka
FROM clanek
JOIN uzivatel ON clanek.autor_id = uzivatel.uzivatel_id
ORDER BY prezdivka;

V příští lekci se podíváme na INNER a OUTER JOIN a seznámíme se s omezením FOREING KEY (cizí klíč).


 

  Aktivity (1)

Článek pro vás napsal vita
Avatar
vita

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 



 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!