Home > Uncategorized > [cz] Úvod do SQL

[cz] Úvod do SQL

October 15th, 2016 Leave a comment Go to comments

SQL je nejběžnější jazyk používaný pro práci s RDBMs (relační databázové systémy). Protože je užitečné umět pracovat s databází, septal jsem stručný přehled operací, které se pomocí SQL dají dělat na jednoduchých konkrétních příkladech, s odkazy na další zdroje.

Nejdřív je třeba mít nějaký databázový server. Je vícero produktů, některé zdarma, jiné placené. Namátkově třeba MySQL (nebo jeho fork MariaDB), Oracle, SQLite, Microsoft SQL Server, … SQL engine také obsahují LibreOffice/OpenOffice Base a Microsoft Access.

Následující informace se budou týkat hlavně MySQL. Většina informací ale platí s drobnými rozdíly pro všechny SQL servery. Jednotlivé příkazy se dají vyzkoušet přímo CTRL(MAC)+C a CTRL(MAC)+V do polčka SQL dotazů. Ale záleží na pořadí – nemůžeme pracovat s tabulkou pokud ještě neexistuje, stejně tak příkaz pro smazání nic nesmaže, pokud tabulka nic neobsahuje.

V první řadě ale potřebujeme databázi. Jeden server jich může hostovat vícero. Často už nějakou databázi uživatel dostane před-vytvořenou. Pokud však má vlastní sql server, může vyvořit novou databázi SQL příkazem:

CREATE DATABASE nazevDatabaze;

Středníkem je zvyk ukončovat SQL dotaz.

Pokud použijeme nějaký grafický nástroj, výběr databáze se provede kliknutím. Pokud pracujeme s databází jen pomocí příkazů, vybereme databázi, se kterou chceme pracovat pomocí use:

USE nazevDatabaze;

A je čas vytvořit první tabulku. Tabulka je něco jako list Excelu, má sloupce. Prázdná tabulka nemá data, tedy řádky. Pro vytvoření tabulky musíme zadat její název a nadefinovat datové typy sloupců. Narozdíl od Excelu mají sloupce typy, což mimo jiného pomáhá databázovému serveru pracovat s daty rychleji a ukládat je na disk efektivněji. Pomocí SQL se tabulka vytvoří takto:

CREATE TABLE lide
(
id int AUTO_INCREMENT,
jmeno varchar(255), 
mesto varchar(255), 
vek int 
);

Pro přehlednost se uvádí na více řádků, ale je to jeden příkaz a dá se napsat na jeden řádek. Nazev tabulky zde je lide. Tabulka má 4 sloupce. První sloupec má název id, je typu int a má speciální vlastnost AUTO_INCREMENT, která způsobí, že pokud při zadávání řádku nezadáme hodnotu sloupce id, systém nám id přiřadí sám. Začíní počítat od 1 a je garantováno, že nikdy nenastaví stejné číslo. Dále se dá specifikovat spousta vlastností sloupce, např. NOT NULL, která vynutí, aby každý řádek obsahoval něco v daném sloupci a nemohl být sloupec NULL (tedy neobsahující konkrétní data). Další užitečná vlastnost je DEFAULT čímž se specifikuje hodnota, která se použije, pokud při vkládání řádku nezadáme konkrétní hodnotu v daném sloupci. Kompetní syntax CREATE TABLE je v mysql manuálu (anglicky) spolu i s nějakými příklady. Datových typů je spousta. Nejpoužívanější jsou longint, int, smallint, tinyint. Mají různou velikost v bytech a umí uložit různě velká čísla. Pro víc informací např. do google datové typy mysql rozsah. Pro čísla s desetinnou čárkou DOUBLE (přesnější ale 2x větší než FLOAT) nebo FLOAT. Pro kratší, délkou omezený text se používá VARCHAR(délka), např. VARCHAR(8) uloží texty až do 8 znaků. Maximum délky typu varchar je VARCHAR(255). Pro delší texty se používá typ TEXT.

Pokud vyrobíme tabulku s nějakými sloupci a pak zjistíme, že jsme nějaký zapomněli, nebo má špatný typ nebo něco jiného, jde strukturu tabulky upravovat dodatečně pomocí SQL příkazu ALTER TABLE. Pro tento článek to není důležité. Pokud používáme grafického správce, umožňuje nám editovat sloupce a jejich vlastnosti v sekci pod názvy Struktura/Structure/Schéma/Scheme nebo pod něcím jako Úprava nebo Alter.

Máme tabulku, potřebujeme do ní dostat data. To můžeme po jednom řádku nebo použít nějaký nástroj, který rozebere třeba CSV soubor a pro každý jeho řádek udělá separátní SQL příkaz INSERT. Je vhodné umět přidat řádek pomocí SQL. To se dělá následovně – vložíme několik řádků:

INSERT INTO lide (`jmeno`, `mesto`, `vek`) VALUES ('Adam', 'Praha', 25);
INSERT INTO lide (jmeno, mesto, vek) VALUES ('Tomáš', 'Chomutov', 32);
INSERT INTO lide (jmeno, mesto, vek) VALUES ('Kateřina', 'Chomutov', 29);

Zde je nutno zmínit ohraničování názvů sloupců a tabulek. Pokud sloupec/tabulka nemá název jako některé slovo z SQL, můžeme ji napsat “jen tak”. Pokud by se ale sloupec jmenoval třeba not, budeme muset to napsat jako `not`, aby sql server věděl, že píšeme název sloupce/tabulky a ne slovo z SQL. První INSERT měl názvy sloupců ohraničené správně pomocí zpětného apostrofu. Hodnoty typu varchar, text, datetime, time se ohraničují apostrofem ‘x’ případně uvozovkami “x” Hodnoty typu číslo se zadávají přímo bez ničeho, případně taky jako řetězec.

Další běžnou operací je SELECT pomocí kterého uděláme nějaký dotaz na databázi. Tímto například zjistíme, kdo z lidí je z Chomutova:

SELECT jmeno FROM lide WHERE mesto = "Chomutov";

SELECT je opět příkaz, který může mít spoustu dalších slov, kombinovat několik tabulek do sebe atd. Ale úplný základ sytaxe je: SELECT, pak následuje seznam sloupců, které chceme získat, případně aggregační či jiné funkce, FROM a název tabulky, ze které chceme data získat, WHERE a výraz s omezeními, která musí platit pro žádané řádky. V našem případě chceme, aby sloupec mesto obsahoval přesně hodnotu “Chomutov”.

S agregační funkcí to vypadá třeba takto – chceme zjistit kolik řádků, tedy lidí je z Chomutova:

SELECT COUNT(*) FROM lide WHERE mesto = "Chomutov";

Vrátí nám to jeden řádek v jednom sloupci a bude obsahovat číslo 2.

Podmínky můžou být mnohem složitější s boolean operátory AND a OR, závorkami a dokoce SQL funkcemi, jejichž seznam je opět v dokumentaci. Vyledání lidí z Chomutova starší 30 let by se udělalo takto:

SELECT * FROM lide WHERE mesto = "Chomutov" AND vek > 30;

Hvězdička znamená “všechny sloupce”.

Napojení dalších tabulek do SELECT dotazu se dělá pomocí JOIN. To téma vyžaduje mít víc než jednu tabulku a nějakou relaci mezi nima. Například tabulka lide jak to máme, kde každý člověk má unikátní id a pak třeba tabulku napady se sloupci clovek_id a napad. Ve sloupci clovek_id by byly cisla lidi, kteří daný nápad vymysleli a ve sloupci nápad by byl text nápadu. Pak bychom mohli udělat dotaz, který by vypsal všechny nápady a ke každému přidal i sloupec s názvem člověka. Delaily jsou ale nad rámec tohoto úvodu:

SELECT napady.napad, lide.jmeno FROM napady LEFT JOIN lide ON lide.id = napady.clovek_id;

Výsledkem bude tabulka nápadů kde v prvním sloupci bude nápad a v druhém jméno člověka, který nápad vymyslel.

Když místo “SELECT sloupce” zadáme “DELETE”, máme dotaz pro smazání řádků. Funguje podobně jako SELECT (je tam podmínka WHERE) ale místo získání výsledků smaže řádky odpovídající podmínce. Pro smazání Adama stačí zadat:

DELETE FROM lide WHERE jmeno = "Adam";

Z těch nejpoužívanějších SQL dotazů ještě UPDATE. Ten provede úpravu řádku. Pokud Kateřina zestárne o jeden rok, provedeme aktualizaci třeba takto:

UPDATE lide SET vek = 30 WHERE jmeno = "Kateřina";

můžeme ale taký použít matematický výraz a reference na existující hodnoty sloupců. Takže zvýšit hodnotu sloupce vek o jedna jde i takto:

UPDATE lide SET vek = vek+1 WHERE jmeno = "Kateřina";

To jsou všechny nejčastěji používané SQL dotazy (klauzule). Jednotlivé dotazy mohou mít víc slov pro složitější a přesnější dotazy. Pro jejich pochopení je však nutno studovat víc jednotlivé dokumentace, nebo hledat konkrétní problém. Například když použijeme v SELECT agregační funkci, získáme výsledek agregace celé tabulky. Pokud ale třeba chceme mít průměry teplot v rocích a máme teploty po měsících, musíme použít GROUP BY a když dáme do google group by years datetime mysql, zjistíme, že potřebujeme DATETIME funkci YEAR:

GROUP BY YEAR(record_date)

Kromě GROUP BY má select i ORDER BY, kde si zadáme podle jakých sloupců výsledky řadit a jestli sestupně nebo vzestupně. Důležité je někdy pořadí slov. Pro SELECT je opět v dokumentaci a vidímě, že nejdřív v dotazu musíme mít GROUP BY … a pak ORDER BY … .

Snad článek pomohl seznámit se s SQL.

Categories: Uncategorized Tags:
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
deadly laser