Professional Documents
Culture Documents
Prednášky
Alexander Šimko
simko@fmph.uniba.sk
Contents I
Organizačné veci
Dátové typy
Výrazy
WHERE a NULL
Contents II
SELECT podrobnejšie
Množinové operácie
Integritné obmedzenia
Contents III
UPSERT
Podmienené výrazy
Agregovanie dát
Normalizácia neformálne
Vnorené SELECTy
Konštrukcia WITH
Textové typy
Práca s textom
Fulltextové vyhľadávanie
Generovanie dát
Skúška
Čo bude na DB2?
Organizačné veci
Section 1
Organizačné veci
Organizačné veci
O prednášajúcom
I Alexander Šimko
I miestnosť I-6
I simko@fmph.uniba.sk
I http://dai.fmph.uniba.sk/~simko
Organizačné veci
O predmete
I http://dai.fmph.uniba.sk/~simko/teaching/db1
I zameraný na tvorbu softvéru s použitím relačných databáz
I PostgreSQL
Organizačné veci
O predmete
Priebeh predmetu
2h prednášok týždenne
I Streda 09:50 B
2h cvičení týždenne
I streda 16:30 H-6, štvrtok 14:50 H-6, štvrtok 16:30 H-6
I za počítačom
I budeme programovať a riešiť úlohy
Organizačné veci
Hodnotenie – Čo bude
I na papier
I všetko, čo dovtedy preberieme
I úlohy budú praktické: napíšte SQL príkaz, vyhodnoťte SQL príkaz,
napíšte, kde je chyba a pod
I dokopy z dvoch písomiek treba získať aspoň 25b
I minimum z jednej písomky nie je
I opravné písomky nebudú
Organizačné veci
Hodnotenie – Čo bude
Hodnotenie – Čo nebude
Stupnica
I máte za to 3 kredity
I budete hodnotení na základe 2 pribežných písomiek
I skúška nebude
I učivo po cca 8. prednášku (presne si ešte povieme)
Organizačné veci
42.86 2015/16
40 38.1 37.1 2016/17
35.82
2017/18
30
% študentov
19.64 19.64
20
14.93
13.43 13.43 11.94 10.45
10 8.27.14 7.14
6.2 6.2
3.57 4.1
0
FX E D C B A
Organizačné veci
80
2017/18
60
60
% študentov
40
20
20
13.33
6.67
0 0
0
FX E D C B A
Organizačné veci
I predmet je za 5 kreditov
I kreditový systém predpokladá záťaz 25-30 hodín na kredit
I to dáva 5 ∗ 25 = 125 hodín práce
I máme 14 týždňov = 13 za semester + 1 cez skúškové
I 125 hodín / 14 týždňov = 8,9 hodín práce týždenne
I prednášky a cviká zaberajú 1,5 + 1,5 = 3 hodiny týždenne
I ostáva v priemere 5,9 hodín samoštúdia týždenne
Čo je databázový systém a prečo by ma mal zaujímať?
Section 2
I perzistencia,
I veľké množstvo dát,
I veľké množstvo používateľov pracujúcich naraz,
I výpadky, napr. počítačovej siete, elektriny a iné chyby.
Čo je databázový systém a prečo by ma mal zaujímať? Výzvy pri tvorbe softvéru
Perzistencia
Zotavenie sa z výpadkov
Čo je to databázový systém?
Tento predmet
1-AIN-121 Matematika 1
Úvod do matematického myslenia
1-AIN-221
Databázy (1)
1-AIN-160 Matematika 3
Diskrétna matematika
1-AIN-222
Databázy (2)
1-AIN-412 Matematika 4
Logika pre informatikov
1-AIN-305
Deduktívne databázy
1-AIN-315
Semištruktúrované dáta
(XML, JSON a NoSQL)
Relačný model dát a SQL
Section 3
Codd, E. F. (1970).
A relational model of data for large shared data banks
Definícia tabuľky
Príklad tabuliek
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
countries ratings
id name user_id film_id rating
1 Slovakia 1 2 10
4 Czech Republic 2 1 9
Relačný model dát a SQL Relačný model dát
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
countries
id name
1 Slovakia
4 Czech Republic
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
ratings
user_id film_id rating
1 2 10
2 1 9
Kľúč tabuľky
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
ratings
user_id film_id rating
1 1 9
1 2 10
2 1 9
2 2 9
2 2 10
Žiaden kľúč
ratings
user_id film_id rating
1 1 9
1 1 9
Relačný model dát a SQL Relačný model dát
Umelý kľúč
ratings
id user_id film_id rating
1 1 1 9
2 1 1 9
Relačný model dát a SQL Relačný model dát
Umelý kľúč
Primárny klúč
Cudzí kľúč
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
countries
id name
1 Slovakia
4 Czech Republic
films = {
(1, Léon : The Professional, 1994, 10),
(2, Django Unchained, 2012, 10),
}
Relačný model dát a SQL Relačný model dát
I duplicity,
I poradie.
Relačný model dát a SQL SQL
Príklad SQL
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
name price
Django Unchained 10
Relačný model dát a SQL SQL
Delenie SQL
Section 4
films
id name year price
Základné SQL príkazy Dva základné DDL príkazy
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
Základné SQL príkazy Štyri základné DML príkazy
SELECT – Syntax
SELECT – Príklad
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
name price
Django Unchained 10
Základné SQL príkazy Štyri základné DML príkazy
UPDATE – Syntax
UPDATE názov_tabuľky
SET názov_stĺpca_1 = nová_hodnota_1,
...,
názov_stĺpca_n = nová_hodnota_n
[WHERE podmienka]
UPDATE – Príklad
films
id name year price
1 Léon: The Professional 1993 10
2 Django Unchained 2012 10
UPDATE films
SET year = 1994
WHERE id = 1
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
Základné SQL príkazy Štyri základné DML príkazy
DELETE – Syntax
DELETE – Príklad
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
films
id name year price
1 Léon: The Professional 1994 10
Základné SQL príkazy Štyri základné DML príkazy
Section 5
Dátové typy
Dátové typy Číselné typy
Celé čísla
smallint
I 2 bajty
I od -32768 do +32767
integer
I 4 bajty
I od -2147483648 do +2147483647
bigint
I 8 bajtov
I od -9223372036854775808 do +9223372036854775807
Dátové typy Číselné typy
real
I 4 bajty
I typicky od ±1 × 10−37 do ±1 × 10+37 (platformovo závislé)
I 6 desatinných miest
double precision
I 8 bajtov
I typicky od ±1 × 10−307 do ±1 × 10+308 (platformovo závislé)
I 15 desatinných miest
Dátové typy Číselné typy
číslo 5:
znamienko exponent mantisa
0 10000001 01000000000000000000000
1
(−1)0 × 2129−127 × (1 + ) = 1 × 22 × 1.25 = 5
4
Dátové typy Číselné typy
číslo 3.3:
znamienko exponent mantisa
0 10000000 10100110011001100110011
1 1 1
(−1)0 × 2128−127 × (1 + + + + ...) =
2 8 64
= 1 × 2 × 1.649999976158142 = 3.299999952316284
http://www.h-schmidt.net/FloatConverter/IEEE754.html
Dátové typy Číselné typy
numeric
I premenlivá dĺžka
I 131072 miest pred desatinnou čiarkou
I 16383 miest za desatinnou čiarkou
zmestí sa
do bigint
nie
numeric
Dátové typy Číselné typy
Reťazce
varchar(n)
I reťazec dĺžky maximálne n znakov,
I kratšie reťazce zeberajú menej miesta
I ak n neuvedieme, dĺžka reťazca nie je obmedzená (PostgreSQL
špecialita)
Dátové typy Reťazcové typy
Textové literály
’Janko Hraško’
’Diannne’’s horse’
Textové literály
Reťazec
’pred’
’met’
’predmet’
Dátové typy Reťazcové typy
Textové literály
’pred’ ’met’
Dátové typy Reťazcové typy
Na čo sú úvodzovky?
Úvodzovky – Príklad
Úvodzovky – Príklad 2
Môže sa hodiť, ak chceme tabuľku/stĺpec pomenovať nejakým vyhradeným
slovom, ktoré nám parser nevezme.
CREATE TABLE user
(
...
)
date
I 4 bajty
I od 4717 p.n.l. po 5874897 n.l.
Dátumový literál
DATE ’YYYY-MM-DD’
DATE ’2015-06-17’
Dátové typy Dátumové a časové typy
time
I 8 bajtov
I od 0:00:00 do 24:00:00 vrátane
Dátové typy Dátumové a časové typy
Časový literál
Formát
TIME ’HH:MM:SS.SSSSSS’
TIME ’23:05:00.000001’
Dátové typy Dátumové a časové typy
Dátum s časom
timestamp
I 8 bajtov
I rozsahy rovnako ako pri dátume a čase
boolean
I 1 bajt
I dve hodnoty – pravda a nepravda
Pravdivý literál
TRUE
Nepravdivý literál
FALSE
Dátové typy NULL hodnoty
NULL hodnoty
users
name telepnone_number
fan123 88083582
johnny NULL
Literál NULL
Section 6
Výrazy
Výrazy Motivácia
SELECT – Výrazy
Motivácia – Riešenie
INSERT – Výrazy
Príklad:
UPDATE – Výrazy
UPDATE názov_tabuľky
SET názov_stĺpca_1 = výraz_1,
...,
názov_stĺpca_n = výraz_n
WHERE booleovský_výraz
Príklad:
UPDATE films
SET price = price * 1.1
WHERE year >= 2015 OR length > 120
Výrazy Výzary v SQL príkazoch
DELETE – Výrazy
Príklad:
Výrazy budujeme z:
I názvov stĺpcov a
I literálov
postupným aplikovaním
I operátorov,
I funkcií a
I zátvoriek.
Výrazy Ako sa budujú výrazy
Čísla – operátory
x + y súčet čísel
x - y rozdiel čísel
x * y súčin čísel
Výrazy Ako sa budujú výrazy
Čísla – operátory
x / y podiel čísel
5.0 / 2 = 2.5
5 / 2 = 2
Delenie nulou?
5 / 0
Čísla – operátory
Čísla – funkcie
http:
//www.postgresql.org/docs/current/static/functions-math.html
Výrazy Ako sa budujú výrazy
5 * NULL → NULL
(5 / NULL) + 1 → NULL
0 * NULL → NULL
NULL / 0 → NULL
Výrazy Ako sa budujú výrazy
GREATEST a LEAST
Booleovské výrazy
I TRUE – pravda
I FALSE – nepravda
I NULL – neznáma hodnota (nevieme)
Výrazy Ako sa budujú výrazy
Porovnania
(6 / 2) > (2 + 1)
FALSE
Výrazy Ako sa budujú výrazy
10 = 10 → TRUE
10 != 10 → FALSE
10 = NULL → NULL
NULL = NULL → NULL
NULL != NULL → NULL
x IS NULL či je x NULL
x IS NOT NULL či x je iné než NULL
10 IS NULL FALSE
NULL IS NULL TRUE
settings
key actual_value default_value
colour red blue
timeout 10 NULL
max_volume NULL NULL
x IS DISTINCT FROM y
I ak ani x ani y nie je NULL, potom rovnako ako x != y,
I ak x,y sú oba NULL, potom vráti FALSE,
I ak je iba jeden NULL, potom TRUE.
výraz_1 OR výraz_2
NOT výraz
Výrazy Ako sa budujú výrazy
AND
3-hodnotová logika – OR
OR
NOT
TRUE FALSE
FALSE TRUE
NULL NULL
Výrazy Ako sa budujú výrazy
BETWEEN
x BETWEEN y AND z
je ekvivalentné
NOT BETWEEN
je ekvivalentné
x < y OR z < x
Výrazy Ako sa budujú výrazy
IN
je ekvivalentné
NOT IN
je ekvivalentné
5 IN (NULL, 6)
5 = NULL OR 5 = 6
NULL OR FALSE
NULL
Výrazy Ako sa budujú výrazy
5 NOT IN (NULL, 6)
5 != NULL AND 5 != 6
NULL AND TRUE
NULL
WHERE a NULL
Section 7
WHERE a NULL
WHERE a NULL
WHERE booleovsky_vyraz
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
3 stellar stellar@email.com NULL
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
3 stellar stellar@email.com NULL
Section 8
Section 9
Sekvencia
CREATE SEQUENCE
DROP SEQUENCE
Funkcia nextval
nextval(nazov_sekvencie)
Príklad
films
id name
1 Léon: The Professional
2 Django Unchained
SELECT podrobnejšie
Section 10
SELECT podrobnejšie
SELECT podrobnejšie SELECT bez FROM
SELECT 5 * (9 - 3) > 15
?column?
t
SELECT podrobnejšie Aliasy stĺpcov
Aliasy stĺpcov
SELECT 5 * (9 - 3) > 15
?column?
t
výraz AS alias_stĺpca
SELECT podrobnejšie Aliasy stĺpcov
name new_price
Léon: The Professional 11
Django Unchained 12
SELECT podrobnejšie Aliasy stĺpcov
Pseudostĺpec *
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
Pseudostĺpec *
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
ORDER BY – Syntax
ORDER BY – Sémantika
ORDER BY
ASC
I riadky sa podľa daného výrazu usporiadajú vzostupne,
I od najmenšieho po najväčší
I default,
DESC
I riadky sa podľa daného výrazu usporiadajú zostupne
I od najväčšieho po najmenší.
SELECT podrobnejšie ORDER BY
ORDER BY – Príklad
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
3 Unbreakable 2000 8
4 Seven Samurai 1954 NULL
ORDER BY – Príklad
ORDER BY
NULLS LAST
I riadky majúce daný výraz NULLový pôjdu na koniec
I default pre ASC
NULLS FIRST
I riadky majúce daný výraz NULLový pôjdu na začiatok
I default pre DESC
SELECT podrobnejšie ORDER BY
ORDER BY – Príklad 2
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
3 Unbreakable 2000 8
4 Seven Samurai 1954 NULL
ORDER BY – Príklad 3
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
3 Unbreakable 2000 8
4 Seven Samurai 1954 NULL
LIMIT
LIMIT číslo
I píše sa za ORDER BY
I obmedzí počet výsledkov na maximálne daný počet
I menej výsledkov bude iba ak samotný SELECT vráti menej riadkov
LIMIT ALL
LIMIT NULL
LIMIT – Príklad
OFFSET
OFFSET číslo
I píše sa za ORDER BY
I preskočí daný počet riadkov
OFFSET 0
OFFSET NULL
I preskočí 0 riadkov
I akokeby sme ani neuviedli
SELECT podrobnejšie LIMIT a OFFSET
OFFSET – Príklad
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
3 Unbreakable 2000 8
4 Seven Samurai 1954 NULL
5 El mariachi 1992 7
6 Bram Stocker’s Dracula 1992 8
SELECT podrobnejšie LIMIT a OFFSET
3 Unbreakable 2000 8
1
4 Seven Samurai 1954 NULL
5 El mariachi 1992 7
2
6 Bram Stocker’s Dracula 1992 8
films
id name year price
1 Léon: The Professional 1994 10
3 Pulp Fiction 1994 10
7 Interview with the Vampire 1994 9
films
id name year price
1 Léon: The Professional 1994 10
3 Pulp Fiction 1994 10
7 Interview with the Vampire 1994 9
year price
1994 10
1994 9
SELECT podrobnejšie DISTINCT
films
id name year price
1 Léon: The Professional 1994 10
3 Pulp Fiction 1994 10
7 Interview with the Vampire 1994 9
year price
1994 10
1994 9
DISTINCT ON
DISTINCT ON
films
id name year price
1 Léon: The Professional 1994 10
3 Pulp Fiction 1994 10
7 Interview with the Vampire 1994 9
year price
1994 10
SELECT podrobnejšie DISTINCT
films
id name year price
1 Léon: The Professional 1994 10
3 Pulp Fiction 1994 10
7 Interview with the Vampire 1994 9
name
Léon: The Professional
SELECT podrobnejšie DISTINCT
je to isté ako
films
id name year price
1 Léon: The Professional NULL 10
3 Pulp Fiction NULL 10
7 Interview with the Vampire NULL 9
name
Léon: The Professional
SELECT podrobnejšie DISTINCT
films
id name year price
1 Léon: The Professional 1994 10
3 Pulp Fiction 1994 10
5 El mariachi 1992 7
7 Interview with the Vampire 1994 9
6 Bram Stocker’s Dracula 1992 8
DISTINCT ON a ORDER BY
SELECT – Rekapitulácia
Section 11
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
ratings
user_id film_id rating
1 1 10
2 1 8
2 2 9
Chceme získať hodnotenia filmov, ale namiesto idčka filmu chceme získať
názov filmu.
JOIN - Získavanie dát z viacerých tabuliek spájaním INNER JOIN
INNER JOIN
ratings
films
user_id film_id rating
id name year price
1 1 10
1 Léon 1994 10
2 1 8
2 Django 2012 10
2 2 9
ratings
films
user_id film_id rating
id name year price
1 1 10
1 Léon 1994 10
2 1 8
2 Django 2012 10
2 2 9
ratings
films
user_id film_id rating
id name year price
1 1 10
1 Léon 1994 10
2 1 8
2 Django 2012 10
2 2 9
name rating
Léon 10
Léon 8
Django 9
JOIN - Získavanie dát z viacerých tabuliek spájaním INNER JOIN
SELECT *
FROM films INNER JOIN ratings
ON film_id = id
je to isté ako
názov_tabuľky_1 JOIN názov_tabuľky_2
ON podmienka
JOIN - Získavanie dát z viacerých tabuliek spájaním Rovnomenné stĺpce
Rovnomenné stĺpce
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
countries
id name
1 Slovakia
4 Czech Republic
SELECT *
FROM users INNER JOIN countries
ON country_id = id
názov_tabuľky.názov_stĺpca
JOIN - Získavanie dát z viacerých tabuliek spájaním Rovnomenné stĺpce
SELECT *
FROM users INNER JOIN countries
ON country_id = countries.id
users
countries
id name email country_id
id name
1 fan123 fan123@gmail.com 1
1 Slovakia
2 johnny spam@spam.com 4
4 Czech Republic
3 stellar my@email.ch NULL
users
countries
id name email country_id
id name
1 fan123 fan123@gmail.com 1
1 Slovakia
2 johnny spam@spam.com 4
4 Czech Republic
3 stellar my@email.ch NULL
users
countries
id name email country_id
id name
1 fan123 fan123@gmail.com 1
1 Slovakia
2 johnny spam@spam.com 4
4 Czech Republic
3 stellar my@email.ch NULL
users
countries
id name email country_id
id name
1 fan123 fan123@gmail.com 1
1 Slovakia
2 johnny spam@spam.com 4
4 Czech Republic
3 stellar my@email.ch NULL
name name
fan123 Slovakia
johnny Czech Republic
stellar NULL
JOIN - Získavanie dát z viacerých tabuliek spájaním LEFT OUTER JOIN
je to isté ako
countries
users
id name
id name email country_id
1 Slovakia
1 fan123 fan123@gmail.com 1
4 Czech Republic
2 johnny spam@spam.com 4
5 Poland
countries
users
id name
id name email country_id
1 Slovakia
1 fan123 fan123@gmail.com 1
4 Czech Republic
2 johnny spam@spam.com 4
5 Poland
countries
users
id name
id name email country_id
1 Slovakia
1 fan123 fan123@gmail.com 1
4 Czech Republic
2 johnny spam@spam.com 4
5 Poland
name name
fan123 Slovakia
johnny Czech Republic
NULL Poland
JOIN - Získavanie dát z viacerých tabuliek spájaním RIGHT OUTER JOIN
je to isté ako
users countries
id name email country_id id name
1 fan123 fan123@gmail.com 1 1 Slovakia
2 johnny spam@spam.com 4 4 Czech Republic
3 stellar my@email.ch NULL 5 Poland
JOIN - Získavanie dát z viacerých tabuliek spájaním FULL OUTER JOIN
users countries
id name email country_id id name
1 fan123 fan123@gmail.com 1 1 Slovakia
2 johnny spam@spam.com 4 4 Czech Republic
3 stellar my@email.ch NULL 5 Poland
SELECT *
FROM users FULL OUTER JOIN countries
ON country_id = countries.id
je to isté ako
countries genres
id name id name
1 Slovakia 1 sci-fi
4 Czech Republic 2 drama
SELECT *
FROM countries CROSS JOIN genres
JOIN - Získavanie dát z viacerých tabuliek spájaním CROSS JOIN
countries genres
id name id name
1 Slovakia 1 sci-fi
4 Czech Republic 2 drama
SELECT *
FROM countries CROSS JOIN genres
id name id name
1 Slovakia 1 sci-fi
1 Slovakia 2 drama
4 Czech Republic 1 sci-fi
4 Czech Republic 2 drama
JOIN - Získavanie dát z viacerých tabuliek spájaním CROSS JOIN
SELECT zoznam_výrazov
FROM názov_tabuľky_1 CROSS JOIN názov_tabuľky_2
WHERE podmienka
je to to isté ako
SELECT zoznam_výrazov
FROM názov_tabuľky_1 INNER JOIN názov_tabuľky_2
ON podmienka
JOIN - Získavanie dát z viacerých tabuliek spájaním CROSS JOIN
názov_tabuľky_1
CROSS JOIN
názov_tabuľky_2,
...
názov_tabuľky_n
JOIN - Získavanie dát z viacerých tabuliek spájaním CROSS JOIN
je to to isté ako:
SELECT zoznam_stĺpcov
FROM názov_tabuľky_1
CROSS JOIN názov_tabuľky_2,
...
názov_tabuľky_n
JOIN - Získavanie dát z viacerých tabuliek spájaním Alias tabuľky
Alias tabuľky
názov_tabuľky AS alias_tabuľky
JOIN - Získavanie dát z viacerých tabuliek spájaním Alias tabuľky
SELECT *
FROM films AS films1
CROSS JOIN films AS films2
JOIN - Získavanie dát z viacerých tabuliek spájaním Alias tabuľky
SELECT *
FROM films AS films1
CROSS JOIN films AS films2
Takto dostaneme:
I dvojice v tvare film1, film1
I okrem dvojice film1, film2 aj dvojicu film2, film1
JOIN - Získavanie dát z viacerých tabuliek spájaním Alias tabuľky
SELECT *
FROM films AS films1
CROSS JOIN films AS films2
WHERE films1.id < films2.id
JOIN - Získavanie dát z viacerých tabuliek spájaním JOINy a WHERE
SELECT zoznam_výrazov
FROM názov_tabuľky_1 JOIN názov_tabuľky_2 ON podmienka
WHERE where_podmienka
...
SELECT zoznam_výrazov
FROM názov_tabuľky_1
INNER JOIN názov_tabuľky_2 ON podmienka
Majú byť vo výsledku všetky riadky jednej tabuľky aj keď pre ne neexistuje
riadok druhej tabuľky spĺňajúci podmienku?
I ak ÁNO, potom OUTER JOIN,
I ak NIE, potom INNER JOIN,
I príklady sme už videli
JOIN - Získavanie dát z viacerých tabuliek spájaním JOINy a WHERE
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
3 stellar my@email.ch NULL
countries
id name
1 Slovakia
4 Czech Republic
SELECT *
FROM users INNER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
JOIN - Získavanie dát z viacerých tabuliek spájaním JOINy a WHERE
SELECT *
FROM users INNER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
SELECT *
FROM users INNER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
SELECT *
FROM users INNER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
SELECT *
FROM users LEFT OUTER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
SELECT *
FROM users LEFT OUTER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
SELECT *
FROM users LEFT OUTER JOIN countries
ON country_id = countries.id
WHERE countries.name = ’Slovakia’
Vnáranie JOINov
films
id name year price
1 Léon: The Professional 1994 10
2 Django Unchained 2012 10
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
3 stellar my@email.ch NULL
countries ratings
id name user_id film_id rating
1 Slovakia 1 1 10
4 Czech Republic 3 2 9
JOIN - Získavanie dát z viacerých tabuliek spájaním Vnáranie JOINov
Ak nepoužijeme zátvorky
je to isté ako
Nesprávny pokus:
SELECT films.name, rating
FROM (films LEFT JOIN ratings ON films.id = ratings.film_id)
INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1
Správne riešenie:
SELECT films.name, rating
FROM films LEFT JOIN
(ratings INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1)
ON films.id = ratings.film_id
JOIN - Získavanie dát z viacerých tabuliek spájaním Vnáranie JOINov
users
id name email country_id
2 johnny spam@spam.com 4
ratings
user_id film_id rating
2 1 10
JOIN - Získavanie dát z viacerých tabuliek spájaním Vnáranie JOINov
Nesprávny pokus:
SELECT films.name, rating
FROM (films LEFT JOIN ratings ON films.id = ratings.film_id)
INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1
Nesprávny pokus:
SELECT films.name, rating
FROM (films LEFT JOIN ratings ON films.id = ratings.film_id)
INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1
Nesprávny pokus:
SELECT films.name, rating
FROM (films LEFT JOIN ratings ON films.id = ratings.film_id)
INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1
Nesprávny pokus:
SELECT films.name, rating
FROM (films LEFT JOIN ratings ON films.id = ratings.film_id)
INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1
Správne riešenie:
SELECT films.name, rating
FROM films LEFT JOIN
(ratings INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1)
ON films.id = ratings.film_id
Správne riešenie:
SELECT films.name, rating
FROM films LEFT JOIN
(ratings INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1)
ON films.id = ratings.film_id
Správne riešenie:
SELECT films.name, rating
FROM films LEFT JOIN
(ratings INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1)
ON films.id = ratings.film_id
Správne riešenie:
SELECT films.name, rating
FROM films LEFT JOIN
(ratings INNER JOIN users ON ratings.user_id = users.id AND
country_id = 1)
ON films.id = ratings.film_id
NATURAL JOIN
SELECT zoznam_stĺpcov
FROM názov_tabuľky_1
NATURAL JOIN názov_tabuľky_2
...
users
countries
id email country_id
country_id name
1 fan123@... 1
1 Slovakia
2 spam@... 4
4 Czech Republic
3 my@... NULL
Section 12
UPDATE – motivácia
films rates
id name year price year rate
1 Léon: The Professional 1994 10 1994 2
2 Django Unchained 2012 10 2012 3
films
id name year price
1 Léon: The Professional 1994 20
2 Django Unchained 2012 30
JOIN a UPDATE, DELETE a INSERT UPDATE
UPDATE
UPDATE názov_cieľovej_tabuľky
SET ...
FROM zoznam_názvov_pomocnych_tabuliek
[WHERE podmienka]
UPDATE – riešenie
films rates
id name year price year rate
1 Léon: The Professional 1994 10 1994 2
2 Django Unchained 2012 10 2012 3
UPDATE – riešenie
films rates
id name year price year rate
1 Léon: The Professional 1994 10 1994 2
2 Django Unchained 2012 10 2012 3
JOIN a UPDATE, DELETE a INSERT UPDATE
UPDATE – riešenie
UPDATE – riešenie
UPDATE – riešenie
films
id name year price
1 Léon: The Professional 1994 20
2 Django Unchained 2012 30
JOIN a UPDATE, DELETE a INSERT UPDATE
rates
films
year rate
id name year price
1994 2
1 Léon: The Professional 1994 10
1994 3
2 Django Unchained 2012 10
2012 3
films
id name year price
1 Léon: The Professional 1994 20
2 Django Unchained 2012 30
JOIN a UPDATE, DELETE a INSERT UPDATE
films rates
id name year price year rate
1 Léon: The Professional 1994 10 1994 2
2 Django Unchained 2012 10 2012 3
corrections
year correction
1994 0.9
2012 1.2
UPDATE films
SET price = films.price * rates.rate * corrections.correction
FROM rates JOIN corrections ON rates.year = corrections.year
WHERE rates.year = films.year
JOIN a UPDATE, DELETE a INSERT DELETE
DELETE
DELETE – príklad
films rates
id name year price year rate
1 Léon: The Professional 1994 10 1994 2
2 Django Unchained 2012 10 2012 3
films
id name year price
1 Léon: The Professional 1994 10
JOIN a UPDATE, DELETE a INSERT DELETE
INSERT
INSERT – Príklad
Koeficient už nebude podľa roku ale bude samostante pre každý film.
Nebudeme ich ale ukladať v tabuľke films ale film_rates.
INSERT INTO film_rates(film_id, rate)
SELECT films.id, rates.rate
FROM films JOIN rates ON films.year = rates.year
Množinové operácie
Section 13
Množinové operácie
Množinové operácie
MNOŽINOVÝ_OPERÁTOR:
I UNION – riadky, ktoré vráti dopyt_1 alebo dopyt_2
I INTERSECT – riadky, ktoré vráti dopyt_1 a zároveň aj dopyt_2
I EXCEPT – riadky, ktoré vráti dopyt_1 ale nevráti dopyt_2
Množinové operácie
UNION – Príklad
users
country
id name country_id
id name
1 fan123 1
1 Slovakia
2 johnny 4
4 Czech Republic
3 stellar NULL
SELECT name FROM users
UNION
SELECT name FROM countries
name
fan123
johnny
stellar
Slovakia
Czech Republic
Množinové operácie
name
fan123
johnny
stellar
fan123@gmail.com
spam@spam.com
my@email.ch
Množinové operácie
je to isté ako
a
b
x SELECT * FROM a
x x
1 UNION
2 1
1 SELECT * FROM b
2 2
2
3 3
2
3
2
Množinové operácie
a
b
x SELECT * FROM a
x
1 INTERSECT
2 x
1 SELECT * FROM b
2 2
2
3
2
3
2
Množinové operácie
a
b
x SELECT * FROM a
x
1 EXCEPT
2 x
1 SELECT * FROM b
2 1
2
3
2
3
2
Množinové operácie
Multimnožinové operácie
x
1
a
b 1
x SELECT * FROM a
x 2
1 UNION ALL
2 2
1 SELECT * FROM b
2 2
2
3 2
2
3 2
2
3
3
Množinové operácie
a
b
x SELECT * FROM a
x
1 INTERSECT ALL x
2
1 SELECT * FROM b 2
2
2 2
3
2
3
2
Množinové operácie
a
b
x SELECT * FROM a
x x
1 EXCEPT ALL
2 1
1 SELECT * FROM b
2 1
2
3 2
2
3
2
Množinové operácie
1. vyhodnotí sa dopyt_1,
2. vyhodnotí sa dopyt_2,
3. na výsledky sa aplikuje (multi)množinový operátor
4. výsledok sa usporiada
5. aplikuje sa LIMIT a OFFSET
Je to to isté ako:
(dopyt_1 OPERÁTOR dopyt_2)
ORDER BY výrazy
LIMIT limit OFFSET offset
Množinové operácie
(SELECT 1, NULL)
UNION
(SELECT 1, NULL)
UNION
(SELECT 1, ’a’)
?column? ?column?
1 NULL
1 a
(SELECT 1, NULL)
INTERSECT ALL
(SELECT 1, NULL)
?column? ?column?
1 NULL
Section 14
Integritné obmedzenia
Integritné obmedzenia
Čo to je?
Na čo to je?
Dátový typ
NOT NULL
CHECK obmedzenie
Pri akejkoľvek zmene riadku (insert, update) musí byť CHECK obmedzenie
splnené. Obmedzenie sa považuje za splnené, ak sa vyhodnotí na:
I TRUE, alebo
I NULL
Integritné obmedzenia CHECK
films
id name price
1 Good film NULL
Integritné obmedzenia CHECK
UNIQUE
Nedovolí aby dva riadky v tabuľke mali v stĺpci tú istú hodnotu (porovnáva
sa operátorom =).
Integritné obmedzenia UNIQUE
UNIQUE – Príklad
CREATE TABLE users
(
id serial,
name varchar(50),
email varchar(50) UNIQUE
)
users
id name email
1 fan123 fan123@gmail.com
UNIQUE a NULLy
users
id name email
1 fan123 NULL
2 johnny NULL
Integritné obmedzenia UNIQUE
Nedovolí aby dva riadky v tabuľke mali v daných stĺpcoch tie isté hodnoty,
t.j. aby sa n-tice tvorené hodnotami uvedených stĺpcov rovnali (porovnáva
sa operátorom =).
Integritné obmedzenia UNIQUE
ratings
user_id film_id rating
1 1 10
1 2 10
Kľúče tabuľky
users
id name email country_id
1 martin martin.josh@gmail.com 1
2 martin martin124@yahoo.com 4
3 sue whatever@mydomain.com 4
I {id} je kľúč,
I {email} je kľúč,
I {id, email} je kľúč,
I {name} neidentifikuje riadky jednoznačne
Integritné obmedzenia Primárny kľúč
Primárny kľúč
users
id name email country_id
1 martin martin.josh@gmail.com 1
2 martin martin124@yahoo.com 4
3 sue whatever@mydomain.com 4
users
id name email country_id
1 martin martin.josh@gmail.com 1
2 martin martin124@yahoo.com 4
3 sue whatever@mydomain.com 4
3 someone my@email.com 6
Integritné obmedzenia Primárny kľúč
Cudzí kľúč
Cudzí kľúč je množina stĺpcov tabuľky, ktorou sa daná tabuľka odkazuje na
primárny kľúč inej tabuľky
countries
id name
1 Slovakia
4 Czech Republic
countries
id name
1 Slovakia
4 Czech Republic
users
id name email country_id
1 martin martin.josh@gmail.com 1
2 martin martin124@yahoo.com 4
3 sue whatever@mydomain.com 5
Integritné obmedzenia Cudzí kľúč
countries
id name
1 Slovakia
4 Czech Republic
dostaneme chybu
ERROR: insert or update on table "users" violates
foreign key constraint "users_country_id_fkey"
countries
id name
1 Slovakia
4 Czech Republic
employees
departments
employee_id
department_id
first_name
department_name
last_name
manager_id
department_id
CREATE script
ON DELETE
ON DELETE CASCADE
ON DELETE CASCADE
countries users
id name id name email country_id
1 Slovakia 8 martin martin.josh@ 1
4 Czech Republic 9 martin martin124@ 4
countries users
id name id name email country_id
1 Slovakia 8 martin martin.josh@ 1
4 Czech Republic 9 martin martin124@ 4
countries users
id name id name email country_id
1 Slovakia 8 martin martin.josh@ 1
4 Czech Republic 9 martin martin124@ 4
ON UPDATE
ON UPDATE CASCADE
ON UPDATE CASCADE
countries users
id name id name email country_id
1 Slovakia 8 martin martin.josh@ 1
4 Czech Republic 9 martin martin124@ 4
countries users
id name id name email country_id
1 Slovakia 8 martin martin.josh@ 1
4 Czech Republic 9 martin martin124@ 4
countries users
id name id name email country_id
1 Slovakia 8 martin martin.josh@ 1
4 Czech Republic 9 martin martin124@ 4
Section 15
UPSERT
UPSERT
UPSERT – motivácia
settings
key value
timeout 30
email admin@domain.org
Chceme vložiť riadok pre kľúč timeout, no keď riadok pre tento kľúč už
existuje, chceme ho aktualizovať.
UPSERT
UPSERT – riešenie
settings
key value
timeout 30
email admin@domain.org
Pseudotabuľka EXCLUDED
Pseudotabuľka EXCLUDED
Pseudotabuľka EXCLUDED
settings
key value
timeout 30
email admin@domain.org
settings
key value
timeout 60
email admin@newdomain.org
UPSERT
settings
key value read_only
timeout 30 false
email admin@domain.org true
INSERT INTO settings (key, value)
VALUES (’timeout’, ’60’),
(’email’, ’admin@newdomain.org’)
ON CONFLICT (key) DO UPDATE
SET value = EXCLUDED.value
WHERE settings.read_only = FALSE
settings
key value read_only
timeout 60 false
email admin@domain.org true
UPSERT
Section 16
Podmienené výrazy
Podmienené výrazy
Podmienené výrazy
CASE – Príklad
SELECT films.id,
CASE WHEN year < 1960 THEN ’archaic’
WHEN year BETWEEN 1960 AND 2000 THEN ’old’
ELSE ’recent’
END AS comment
FROM films
Podmienené výrazy
CASE výraz_0
WHEN výraz_1 THEN výsledok_1
[WHEN výraz_2 THEN výsledok_2]
...
[WHEN výraz_n THEN výsledok_n]
[ELSE výsledok_else]
END
Hodnotou celého výrazu je:
I výraz výsledok_i prvej vetvy i, pre ktorú sa porovnanie
výraz_i = výraz_0 vyhodnotí na TRUE
I ináč je výsledkom výraz výsledok_else
Teda ak výraz is NULL, výsledkom je výraz výsledok_else
Podmienené výrazy
CASE – Príklad
SELECT name,
CASE price
WHEN 0 THEN ’free’
ELSE price::VARCHAR
END
FROM films
Pretypovanie
hodnota::typ
COALESCE
COALESCE – Príklad
SELECT user_name,
COALESCE(countries.name, ’No country’) as country_name
FROM users
LEFT JOIN countries ON users.country_id = countries.id
Podmienené výrazy
NULLIF
NULLIF(hodnota_1, hodnota_2)
NULLIF – Príklad
SELECT user_name,
NULLIF(countries.name, ’No country’) as country_name
FROM ...
Agregovanie dát
Section 17
Agregovanie dát
Agregovanie dát Agregačné funkcie
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 12 4
count
3
Agregovanie dát Agregačné funkcie
Agregačné funkcie
count(výraz)
I vráti počet riadkov, pre ktoré sa výraz vyhodnotí na neNULLovú
hodnotu
Agregovanie dát Agregačné funkcie
Agregačné funkcie
sum(výraz)
I vyhodnotí výraz pre každý riadok a získané hodnoty sčíta
avg(výraz)
I vyhodnotí výraz pre každý riadok a zo získaných hodnôt spraví
aritmentický priemer
max(výraz)
I vyhodnotí výraz pre každý riadok a zo získaných hodnôt vezme
maximum
min(výraz)
I vyhodnotí výraz pre každý riadok a zo získaných hodnôt vezme
minimum
Agregovanie dát Agregačné funkcie
Agregačné funkcie
bool_and(výraz)
I vyhodnotí výraz pre každý riadok
I vráti true ak všetky hodnoty sú true, ináč false
I nikdy nevráti NULL
bool_or(výraz)
I vyhodnotí výraz pre každý riadok
I vráti true ak aspoň jedna hodnota je true, ináč false
I nikdy nevráti NULL
Agregovanie dát Agregačné funkcie
1. vykonajú sa JOINy
2. vyberú sa riadky spĺňajúce WHERE podmienku
3. zatiaľ máme vo všeobecnosti tabuľku s veľa riadkami
4. aplikujú sa agregačné funkcie, čím dostaneme jeden riadok
5. idú ďalšie fázy (rekapitulácia bude neskôr)
Agregovanie dát Agregačné funkcie
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 12 4
count
3
Agregovanie dát Agregačné funkcie
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 12 4
avg count
6.667 3
Agregovanie dát Agregačné funkcie
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 12 4
Agregovanie dát Agregačné funkcie
user_id count
12 5
Stĺpec user_id je typu číslo, nie pole čísel. Nevieme, ktorú z hodnôt si
vybrať.
Agregovanie dát Agregačné funkcie
users
id name country_id
1 fan123 1
2 johnny 4
3 stellar NULL
count count
3 2
Agregovanie dát Agregačné funkcie
ratings
user_id film_id rating
1 1 10
1 6 2
2 1 9
FILTER
názov_agregačnej_funkcie(parametre)
FILTER (WHERE podmienka)
SELECT count(CASE
WHEN rating > 5 THEN 1
ELSE NULL
END),
avg(CASE
WHEN rating <= 5 THEN rating
ELSE NULL
END)
FROM ratings
Agregovanie dát GROUP BY
GROUP BY
GROUP BY
SELECT zoznam_select_výrazov
FROM názov_tabuľky
WHERE podmienka
GROUP BY goup_by_výraz_1, ..., group_by_výraz_n
Ako to funguje:
I vezme zadanú tabuľku
I aplikuje WHERE podmienku
I riadky rozdelí do skupín podľa výrazov group_by_výraz_1, ...,
group_by_výraz_n
I na každú skupinu sa aplikujú agregačné funkcie
I každá skupina v pôvodnej tabuľke sa stane riadkom v novej tabuľke
Agregovanie dát GROUP BY
GROUP BY – Príklad
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 12 4
Agregovanie dát GROUP BY
GROUP BY – Príklad
GROUP BY – Príklad
user_id count
1 3
2 2
Agregovanie dát GROUP BY
GROUP BY – Príklad 2
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 6 2
3 7 8
3 6 8
Agregovanie dát GROUP BY
GROUP BY – Príklad 2
GROUP BY – Príklad 2
SELECT zoznam_select_výrazov
FROM názov_tabuľky
WHERE podmienka
GROUP BY group_by_výraz_1, ..., group_by_výraz_n
GROUP BY – Príklad 3
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 6 2
3 7 4
3 6 8
Agregovanie dát GROUP BY
GROUP BY – Príklad 3
GROUP BY – Príklad 3
?column? count
true 3
false 4
Agregovanie dát GROUP BY
under count
true 3
false 4
Agregovanie dát GROUP BY
films
id name year price
3 Ubreakable 2000 8
2 Django Unchained 2012 10
4 Seven Samurai 1954 NULL
6 Bram Stocker’s Dracula 1992 NULL
1 Léon: The Professional 1994 NULL
SELECT price, count(*)
FROM films
GROUP BY price
price count
8 1
10 1
NULL 3
Agregovanie dát GROUP BY
Poradie vykonávania
1. vykonajú sa JOINy
2. vyberú sa riadky spĺňajúce WHERE podmienku
3. riadky sa rozdelia do skupín podľa GROUP BY
4. aplikujú sa agregačné funkcie, čím dostaneme jeden riadok pre každú
skupinu
5. ...
Tým pádom nemôžeme agregačné funkcie použiť vo WHERE časti
Agregovanie dát HAVING
HAVING
HAVING booleovský_výraz
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_id
FROM ratings
GROUP BY film_id
HAVING count(*) >= 2
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 6 2
3 7 8
3 6 8
Agregovanie dát HAVING
HAVING – Príklad
HAVING – Príklad
film_id count
1 1
2 1
6 3
7 2
Agregovanie dát HAVING
HAVING – Príklad
film_id count
1 1
2 1
6 3
7 2
Agregovanie dát HAVING
HAVING – Príklad
film_id count
6 3
7 2
Agregovanie dát HAVING
HAVING – Príklad
film_id
6
7
Agregovanie dát Agregovanie a primárny kľúč
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
ratings
user_id film_id rating
1 1 10
1 6 2
1 7 8
2 2 9
2 12 4
Agregovanie dát Agregovanie a primárny kľúč
user_id count
1 3
2 2
Agregovanie dát Agregovanie a primárny kľúč
name count
fan123 3
johnny 2
Agregovanie dát Poradie agregovania
string_agg(výraz, oddeľovač)
excercise_tag
excercise_id tag
1 join
1 aggregation
2 join
2 subselect
3 subselect
3 join
Agregovanie dát Poradie agregovania
SELECT excercise_id,
string_agg(tag, ’,’) AS excercise_type
FROM excercise_tag
GROUP BY excercise_id
excercise_id excercise_type
1 join,aggregation
2 join,subselect
3 subselect,join
Agregovanie dát Poradie agregovania
ORDER BY
SELECT excercise_id,
string_agg(tag, ’,’ ORDER BY tag) AS excercise_type
FROM excercise_tag
GROUP BY excercise_id
excercise_id excercise_type
1 aggregation,join
2 join, subselect
3 join, subselect
Agregovanie dát Poradie agregovania
ORDER BY
SELECT – Rekapitulácia
Section 18
payments
user_id date payment
1 ... 20
3 ... 5
2 ... 23
3 ... 20
2 ... 18
3 ... 20
4 ... 70
Viac zoskupovaní naraz
user_id total_payment
1 20
2 41
3 45
4 70
176
Ručné riešenie
UNION ALL
GROUPING SETS
... GROUP BY
GROUPING SETS (grouping_set_1, ..., grouping_set_n)
kde grouping_set_i je
Ďalší príklad
ROLLUP
GROUPING SETS (
(s_1, s_2, ..., s_n-1, s_n),
(s_1, s_2, ..., s_n-1),
...
(s_1, s_2),
(s_1),
()
)
Viac zoskupovaní naraz
ROLLUP
CUBE
GROUPING SETS (
...
každá podmnožina (s_1, s_2, ..., s_n-1, s_n)
...
)
Viac zoskupovaní naraz
CUBE
GROUPING SETS (
(s_1, s_2, s_3),
(s_1, s_2 ),
(s_1, s_3),
( s_2, s_3),
(s_1 ),
( s_2 ),
( s_3),
( )
)
Viac zoskupovaní naraz
http://www.postgresql.org/docs/current/static/
queries-table-expressions.html#QUERIES-GROUPING-SETS
Viac zoskupovaní naraz
brand sum
Banana 43
Hot shirts and son 5
NULL 20
NULL 68
Viac zoskupovaní naraz
Funkcia GROUPING
Funkcia GROUPING
user_id brand size payment
1 Banana M 20
3 Hot shirts and son L 5
2 Banana S 23
3 NULL S 20
SELECT brand,
sum(payment),
GROUPING(brand)
FROM payments
GROUP BY GROUPING SETS ( (brand), () )
brand sum grouping
Banana 43 0b0
Hot shirts and son 5 0b0
NULL 20 0b0
NULL 68 0b1
Viac zoskupovaní naraz
Funkcia GROUPING
SELECT brand,
sum(payment),
GROUPING(brand) AS g_b,
GROUPING(size) AS g_s,
GROUPING(brand, size) AS g_bs
FROM payments
GROUP BY GROUPING SETS ( (brand), (size), () )
Funkcia GROUPING
SELECT CASE
WHEN GROUPING(brand) = 1 THEN ’all’
ELSE brand
END AS brand,
sum(payment)
FROM payments
GROUP BY GROUPING SETS ( (brand), () )
brand sum
Banana 43
Hot shirts and son 5
NULL 20
all 68
Viac zoskupovaní naraz
Komplikácia
Section 19
Normalizácia neformálne
Normalizácia neformálne
Normálne formy:
I tabuľka je v 1., 2., ... normálnej forme ak spĺňa isté vlastnosti
I každá normálna forma hovorí, že tabuľka je bez istého typu defektov
I definície sú pomerne technické
Základná myšlienka:
users
id name email country_id
fan123@gmail.com
1 fan123 1
second@email.com
2 johnny spam@spam.com 4
users
id name email country_id
1 fan123 fan123@gmail.com 1
1 fan123 second@email.com 1
2 johnny spam@spam.com 4
Vznikla duplicita
users
id name email country_id
1 fan123 fan123@gmail.com 1
1 fan123 second@email.com 1
2 johnny spam@spam.com 4
Normalizácia neformálne
users
id name email country_id
1 fan123 fan123@gmail.com 1
1 fan123 second@email.com 1
2 johnny spam@spam.com 4
Normalizácia neformálne
users
id name email country_id
1 fan123 fan123@gmail.com 1
1 fan123 second@email.com 1
1 fan123 third@email.com 1
2 johnny spam@spam.com 4
Normalizácia neformálne
users
id name email country_id
1 fan123 fan123@gmail.com 1
1 fan123 second@email.com 1
2 johnny spam@spam.com 4
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
Normalizácia neformálne
users
id name email country_id
1 fan123 fan123@gmail.com 1
2 johnny spam@spam.com 4
users
id name email country_id
1 fan123 NULL 1
2 johnny spam@spam.com 4
users
id name email country_id
1 fan123 fan123@gmail.com 1
1 fan123 second@email.com 1
2 johnny spam@spam.com 4
SELECT *
FROM users INNER JOIN emails ON emails.user_id = users.id
WHERE email = ’second@email.com’
Normalizácia neformálne
contacts
user_id email telephone
1 fan123@gmail.com 22-35-566
1 second@email.com 22-35-566
2 spam@spam.com 95300-164
2 spam@spam.com 14536-337
emails telephones
user_id email user_id telephone
1 fan123@gmail.com 1 22-35-566
1 second@email.com 2 95300-164
2 spam@spam.com 2 14536-337
Návrh databáz / Dátové modelovanie
Section 20
Čo je to model?
Čo je to modelovanie?
Doména
I bankovníctvo,
I predaj leteniek,
I výroba liekov,
I ...
Návrh databáz / Dátové modelovanie Pojmy
Dátový model
Modely
Entitno-relačný model
Príklad
I Janko Hraško
I Databases (1)
I ISIC number S 123 456 789 012 X
Návrh databáz / Dátové modelovanie Entitno-relačný model
Príklad
D = {Janko_Hrasko, Db1, ISIC_S123456789012X, ...}
Návrh databáz / Dátové modelovanie Entitno-relačný model
I podmnožiny domény
I množiny entít, ktoré sú pre nás (aplikáciu) zaujímavé
Návrh databáz / Dátové modelovanie Entitno-relačný model
Students ⊆ D
I všetci študenti na FMFI,
I Students = {Janko_Hrasko, ...}
Courses ⊆ D
I všetky predmety vyučované na FMFI
I Courses = {Db1, ..}
ISICs ⊆ D
I všetky ISICy študentov FMFI
I ISICs = {ISIC _S123456789012X , ...}
Návrh databáz / Dátové modelovanie Entitno-relačný model
name
I name : D → Strings
I name(JankoHasko) = ’Janko’
I name(ISIC_S123456789012X) nie je definované
birth date
I birth_date : D → Dates
I birth_date(JankoHasko) = 1-1-1990
I birth_date(ISIC_S123456789012X) nie je definované
Návrh databáz / Dátové modelovanie Entitno-relačný model
I entity sú vo vzťahoch
I vzťah ako relácia
Návrh databáz / Dátové modelovanie Entitno-relačný model
A:B
1:1
I jedna entina v prvej množine je vo vzťahu s maximálne jednou entitou
z druhej množiny
I a opačne
1:N
I jedna entina v prvej množine je vo vzťahu s ľubovoľne veľa entitami z
druhej množiny,
I no jedna entita z druhej množiny je vo vzťahu maximálne s jednou
entitou z prvej množiny
N:1
I to isté ako 1:N, len obrátene
M:N
I jedna entina v prvej množine je vo vzťahu s ľubovoľne veľa entitami z
druhej množiny
I a opačne
year
I rok, v ktorom má zapísaný predmet
I year : is_enrolled_in → Integers
I year ((JankoHrasko, Db1)) = 2015
final grade
I výsledná známka
I final_grade : is_enrolled_in → Grades
I final_grade((JankoHrasko, Db1)) = A
Návrh databáz / Dátové modelovanie Entitno-relačný model
Štruktúru
I názvy množín entít
I názvy a typy atribútov
I názvy, typy a kardinalita vzťahov
Dáta
I obsah množín entít
I hodnoty atribútov
I obsah vzťahov
krabička s položkami
students
courses
name
name
surname
recommended semester
birth date
theses
isics
name
number
goal
valid until
Návrh databáz / Dátové modelovanie Štruktúra entitno-relačného modelu UML diagramom
students
courses
is enrolled in
name
name
surname
recommended semester
birth date
works on
owns
theses
isics
name
number
goal
valid until
Návrh databáz / Dátové modelovanie Štruktúra entitno-relačného modelu UML diagramom
"číslo" pri čiare – počet entít z danej množiny priradených jednej entite z
druhej množiny
students
courses
is enrolled in
name
name
surname * *
recommended semester
birth date
1
1 works on
owns
1
* theses
isics
name
number
goal
valid until
Návrh databáz / Dátové modelovanie Štruktúra entitno-relačného modelu UML diagramom
názov vzťahu
názov atribútu 1
názov atribútu 2
is enrolled in
year
final grade
students
courses
is enrolled in
name
name
surname * *
recommended semester
birth date
1 works on
1 owns
1
* theses
isics
name
number
goal
valid until
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students
students
id
name
name
surname
surname
birth date
birth_date
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students
theses
works on
name
1 name
surname *
goal
birth date
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students theses
id id
name name
surname goal
birth_date student_id
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students
isics
owns
name
1 1 number
surname
valid until
birth date
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students isics
id id
name number
surname valid_until
birth_date student_id
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students isics
id id
name number
surname valid_until
birth_date student_id
students isics
id id
name number
surname valid_until
birth_date student_id
students
courses
is enrolled in
name
name
surname * *
recommended semester
birth date
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students
courses
enrolled
id
id
name student_id
name
surname course_id
recommended_semester
birth_date
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
is enrolled in
year
final grade
students
courses
is enrolled in
name
name
surname * *
recommended semester
birth date
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
students enrolled
courses
id student_id
id
name course_id
name
surname year
recommended_semester
birth_date final_grade
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
Obdobne
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
Roly
teachers theses
supervisor supervises
name 1 name
*
surname goal
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
Roly
supervisor supervises
teachers 1 * theses
name name
surname oponent opposes goal
1 *
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
Roly
theses
teachers
id
id name
name goal
surname supervisor_id
oponent_id
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
N-árne vzťahy
vzťah môže byť nielen medzi dvomi entitali ale medzi N entitami
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
firms
terms
owns *
*
*
owners
* contracts
name
* terms
surname
signs
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
firms
terms
owns *
*
*
owners
* contracts
name
* terms
surname
signs
T.j. koľko zmlúv može podpisovať jeden majiteľ pre jednu firmu.
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
films
name
actors
studios *
1 name
name
surname
hires
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
films
name
*
actors
studios hires * 1
1 name
name *
surname
Kedy sa to hodí?
I ak množine vieme dať zmysluplné iné meno než sa volal vzťah, alebo
I ak jej vieme dať zmysluplné atribúty
films
name
contracts actors
studios * 1
1 duration name
name *
salary surname
Návrh databáz / Dátové modelovanie Transformovanie entitno-relačného modelu na relačný model
Section 21
Podmnožiny modeluje ak
I potrebujeme vedieť povedať, že entita do danej podmnožiny
patrí/nepatrí
I ak entity z danej podmnožiny majú nejaké atribúty navyše
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
Animals
I age
I weight
Dogs
I has docked tail (má skrátený chvost)
Cats
Pets
I name
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
animals
age
weight
dogs
animal_id
has_docked_tail
animals
cats
id
age animal_id
weight
pets
animal_id
name
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
Výhody
I žiadna duplicita stĺpcov (stĺpce sa neopakujú)
I žiadne nepotrebné veci navyše
I entity z jednej množiny v jednej tabuľke
Nevýhody
I zložitejšia práca s dátami:
I ak chceme všetky atribúty, musíme JOINovať,
I ak chceme prvky z viacerých podmnožín, musíme použiť množinové
operácie
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
Všetko dokopy
Všetko dokopy
animals
id
age
weight
is_dog
has_docket_tail
is_cat
is_pet
name
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
Všetko dokopy
Výhody
I žiadna duplicita stĺpcov (stĺpce sa neopakujú)
I štací pristupovať do jednej tabuľky:
I netreba JOINovať,
I množinové operácie na úrovni booleovského vyrazu nad stĺpcami is_
Nevýhody
I pri veľkom počte atribútov v podmnožinách sa veľa miesta zbytočne
minie na NULL hodnoty atribútov, ktoré pre dané entity nie sú
relevantné
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
Tabuľka bude ukladať entity, ktoré patria práve do tých množín, pre ktoré
bola vytvorená (a do ostatných množín nepatria).
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
animals
id
age
weight
id id id
age age age
weight weight weight
has_docked_tail name
animals_dogs_pets animals_cats_pets
id id
age age
weight weight
has_docked_tails name
name
Návrh databáz / Dátové modelovanie – Pokračovanie Podmnožiny
Výhody
I priestor sa nemíňa na NULL hodnoty
I ak chceme všetky atribúty tej istej entity, nepotrebujeme JOINy –
všetky jej atribúty sú v jednej tabuľke
Nevýhody
I ten istý atribút je vo viacerých tabuľkách
I ak chceme všetky entity z jednej množiny, vo všeobecnosti musíme
zjednotiť výsledky z viacerých tabuliek, napr. pre všetky psy musíme
zjenotiť animals_dogs a animals_dogs_pets.
Návrh databáz / Dátové modelovanie – Pokračovanie Vypočítané množiny
Vypočítané množiny
Nie všetky množiny predstavujú nejakú novú informáciu, ale vieme ich
vypočítať z ostatných dát.
Vypočítané množiny
persons
name
surname
birth date
students teachers
*
is enrolled in
* *
teaches
*
courses
name
Vypočítané množiny
Students
množina všetkých entít z Persons, ktoré sú vo vzťahu enroled_in s
nejakou entitou z Courses
Teachers
množina všetkých entít z Persons, ktoré sú vo vzťahu teaches s nejakou
entitou z Courses
Návrh databáz / Dátové modelovanie – Pokračovanie Vypočítané množiny
Vypočítané množiny
Vypočítané množiny
persons
id
name
surname
birth_date
enrolled teaches
person_id person_id
course_id course_id
courses
id
name
Návrh databáz / Dátové modelovanie – Pokračovanie Vypočítané množiny
Vypočítané množiny
Pohľad (VIEW)
Pohľad – Syntax
Pohľad – Príklad
Pohľad
Students
I množina všetkých študentov závisí od kontextu,
I v tomto prípade je kontextom čas
I napr. v roku 2014 som študentom a v roku 2015 už nie som,
Návrh databáz / Dátové modelovanie – Pokračovanie Kontextovo závislé množiny
persons
enrolled in
name
surname year
birth date
SELECT *
FROM students(2015)
WHERE birth_date > DATE ’1993-06-07’
Návrh databáz / Dátové modelovanie – Pokračovanie Typy a reifikované množiny
Typ entity
Typ entity
je množina všetkých entít s danou vlastnosťou.
Návrh databáz / Dátové modelovanie – Pokračovanie Typy a reifikované množiny
Typ entity
animals
age
weight
dogs cats
Typ entity
Typ entity
if(input_type == ’cats’) {
SELECT * FROM cats;
} else if (input_typ == ’dogs’) {
SELECT * FROM dogs;
}
if(input_type == ’cats’) {
SELECT * FROM animals WHERE is_cat = TRUE;
} else if (input_typ == ’dogs’) {
SELECT * FROM animals WHERE is_dog = TRUE;
}
Návrh databáz / Dátové modelovanie – Pokračovanie Typy a reifikované množiny
Reifikovaná množina
Reifikovaná množina
dogs cats
Dogs a Cats
sú potom vypočítané množiny – patria do nich také entity ktoré majú
naviazaný daný typ
Návrh databáz / Dátové modelovanie – Pokračovanie Typy a reifikované množiny
Reifikovaná množina
animals
types
id
id
weight
name
type_id
Reifikovaná množina
products
price
weight
Meta modelovanie
Meta modelovanie
1
is of type
*
has value
value
Návrh databáz / Dátové modelovanie – Pokračovanie Meta modelovanie
Meta modelovanie
has
attributes type_id attribute_id
types
id name 1 1
id name
1 price 1 2
1 book
2 weight 1 3
2 mouse
3 author 2 1
2 2
has_value
products
product_id attribute_id value
id type_id
1 1 10
1 1
1 2 2
3 2
1 3 Bram Stocker
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
universities
1
1
*
*
faculties departments
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
universities
1
*
faculties
1
*
departments
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
Veci by sme mali mať v modeli uložené len raz a ostatné veci z nich
vypočítať.
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
universities
1
1
*
*
faculties 1 * departments
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
universities
faculties 1 * departments
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
Albert Einstein
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
boards rows
1 * row number
cells
column number
symbol
Návrh databáz / Dátové modelovanie – Pokračovanie Návrhové princípy
cells
boards row number
1 * column number
symbol
Section 22
Vnorené SELECTy
Vnorené SELECTy
Vnorený SELECT
(SELECT ... )
Vnorené SELECTy Skalárne vnorené SELECTy
SELECT *
FROM films AS f
WHERE f.year = (SELECT min(year) FROM films)
Vnorené SELECTy Skalárne vnorené SELECTy
SELECT *
FROM films AS f
WHERE f.year = (SELECT min(year) FROM films)
Pre každý film chceme zistiť o koľko rokov bol natočený neskôr ako
najstarší film.
Pre každý film chceme vedieť koľko filmov bolo vyrobených pred ním.
Pre každý film chceme vedieť koľko filmov bolo vyrobených pred ním.
Pre každý film získaj jeden film, ktorý bol natočený aspoň rok po ňom.
dostaneme chybu
dostaneme chybu
I operátory ako IN, NOT IN, SOME, ALL pracujú so zoznamom hodnôt
I tabuľku s jednym sĺpcom môžeme chápať ako zoznam hodnôt
I zoznam hodnôt môžme nahradiť vnoreným SELECTom, ktorý vracia
takúto tabuľku
Vnorené SELECTy Vnorený SELECT ako zoznam hodnôt
Operátor IN
hodnota IN subquery
Operátor IN – Príklad
SELECT *
FROM films
WHERE id IN (SELECT film_id FROM ratings)
Vnorené SELECTy Vnorený SELECT ako zoznam hodnôt
Operátor NOT IN
SELECT *
FROM departments
WHERE department_id NOT IN (SELECT department_id
FROM employees)
Vnorené SELECTy Vnorený SELECT ako zoznam hodnôt
Pozor na NULLy
SELECT *
FROM departments
WHERE department_id NOT IN (SELECT department_id
FROM employees)
SELECT *
FROM departments
WHERE department_id NOT IN (10, 100, NULL, 50)
Vnorené SELECTy Vnorený SELECT ako zoznam hodnôt
Pozor na NULLy
sa vyhodnotí na:
I FALSE pre department_id 10, 100, 50
I NULL pre všetky ostatné department_id
Predčasné ukončenie
SELECT *
FROM departments AS d
WHERE manager_id IN (SELECT manager_id
FROM employees AS e
WHERE d.id != e.department_id)
Vnorené SELECTy Vnorený SELECT ako zoznam hodnôt
Operátor ANY/SOME
SELECT *
FROM films AS f
WHERE price < ANY (SELECT price
FROM films AS f2
WHERE f2.id != f.id)
Vnorené SELECTy Vnorený SELECT ako zoznam hodnôt
Operátor ALL
Zoznam filmov, ktoré majú nižšiu cenu ako všetky ostatné filmy
SELECT *
FROM films AS f
WHERE price < ALL (SELECT price
FROM films AS f2
WHERE f2.id != f.id)
Vnorené SELECTy EXISTS
Operátor EXISTS
EXISTS subquery
I vráti TRUE práve vtedy keď subquery vráti aspoň jeden riadok
I je jedno koľko stĺpcov subquery vracia
I vrátené hodnoty sa ignorujú – podstatné je, či vráti nejaký riadok
I negácia
Vnorené SELECTy EXISTS
Získame iba také filmy, pre ktoré neexistuje starší lacnejší film
SELECT *
FROM films AS f
WHERE NOT EXISTS
(SELECT NULL
FROM films AS f2
WHERE f2.year < f.year AND f2.price < f.price)
Vnorené SELECTy EXISTS
SELECT avg(tmp.price)
FROM (SELECT price
FROM films
ORDER BY year DESC
LIMIT 10) AS tmp
SELECT *
FROM departments AS d
CROSS JOIN (SELECT *
FROM employees AS e
WHERE e.department_id = d.department_id
ORDER BY salary DESC
LIMIT 3) AS top_employees
Vnorené SELECTy Vnorený SELECT namiesto názvu tabuľky
SELECT *
FROM departments AS d
CROSS JOIN LATERAL (SELECT *
FROM employees AS e
WHERE e.department_id = d.department_id
ORDER BY salary DESC
LIMIT 3) AS top_employees
Vnorené SELECTy Vnorený SELECT namiesto názvu tabuľky
I na veľa miestach
I avšak nie všade, napr. nie v CHECK obmedzení
I niekedy to nie je jasné ani z PostgreSQL dokumentácie:(
I vyvíja sa to v čase, napr. UPDATE v časti SET od verzie 9.5
Konštrukcia WITH
Section 23
Konštrukcia WITH
Konštrukcia WITH
Čo je to WITH?
Syntax
WITH
názov_1 [(stĺpec_1,..., stĺpec_n1)] AS (príkaz_1),
...
názov_m [(stĺpec_1,..., stĺpec_nm)] AS (príkaz_m)
hlavný_príkaz
Vyhodnocovanie
WITH dist_ratings AS (
SELECT DISTINCT ON (user_id, film_id)
user_id, film_id, rating
FROM ratings ORDER BY user_id, film_id, time DESC
),
top_10 AS (
SELECT film_id FROM dist_ratings
GROUP BY film_id ORDER BY avg(rating) DESC LIMIT 10
),
top_plays AS (
SELECT * FROM plays WHERE film_id IN (SELECT * FROM top_10)
)
SELECT * FROM actors WHERE EXISTS
(SELECT NULL FROM top_plays WHERE actor_id = id)
Konštrukcia WITH WITH na sprehľadnenie zápisu SQL príkazov
salaries
user_id year salary
1 2015 700
2 2015 1800
2 2014 1750
3 2014 320
WITH avg_salary AS (
SELECT avg(salary)
FROM salaries
)
SELECT avg_salary
Konštrukcia WITH WITH na sprehľadnenie zápisu SQL príkazov
salaries
user_id year salary
1 2015 700
2 2015 1800
2 2014 1750
3 2014 320
salaries
user_id year salary
1 2015 700
2 2015 1800
2 2014 1750
3 2014 320
avg
1142.50
Konštrukcia WITH WITH na sprehľadnenie zápisu SQL príkazov
salaries
user_id year salary
1 2015 700
2 2015 1800
2 2014 1750
3 2014 320
WITH avg_salary AS (
SELECT avg(salary)
FROM salaries
)
SELECT avg_salary
WITH
názov_1 [(stĺpec_1,..., stĺpec_n1)] AS (príkaz_1)
hlavný_príkaz
salaries
user_id year salary
1 2015 700
2 2015 1800
2 2014 1750
3 2014 320
WITH avg_salary(in_year) AS (
SELECT avg(salary)
FROM salaries
WHERE year = in_year
)
SELECT avg_salary(2015) - avg_salary(2014)
Konštrukcia WITH WITH v kombinácii s INSERT, UPDATE, DELETE
RETURNING *
RETURNING výraz_1 AS názov_1, ..., výraz_n AS názov_n
I píšu sa na koniec príkazov INSERT, UPDATE, DELETE
Konštrukcia WITH WITH v kombinácii s INSERT, UPDATE, DELETE
x y
2 0
2 1
Konštrukcia WITH WITH v kombinácii s INSERT, UPDATE, DELETE
data
a b
1 1
1 2
deleted_b
2
Konštrukcia WITH WITH v kombinácii s INSERT, UPDATE, DELETE
data
a b
1 1
1 2
UPDATE data
SET b = 3 * b
RETURNING b AS new_b
new_b
3
6
Konštrukcia WITH WITH v kombinácii s INSERT, UPDATE, DELETE
id
1
Konštrukcia WITH WITH v kombinácii s INSERT, UPDATE, DELETE
Problém
Neúspešná oprava
Problém
WITH
...
názov_i ... AS (príkaz_i),
...
hlavný_príkaz
WITH updated_salaries AS (
UPDATE users
SET salary = 1.1 * salary
RETURNING id, current_date, salary
)
INSERT INTO salary_history (user_id, date, salary)
SELECT * FROM updated_salaries
Základné info o texte
Section 24
Čo je to text?
Unicode
Napr:
latinkové A → 65
čínsky znak pre číslo jedna → 19968
základný smajlík → 128528
UTF-32
Zakóduje každý Unicode code point ako postupnosť 32 bitov (code unit).
UTF-8
Zakóduje každý Unicode code point ako postupnosť 8, 16, 24, alebo 32
bitov.
I latinka a základné znaky sa kódujú pomocou 8 bitov,
I ostatné s viac bitmi
Základné info o texte
UTF-16
Príklad
den
znaky d e n
Unicode code points 100 101 110
UTF-16 code units 0x0064 0x0065 0x006E 48 bitov
UTF-8 code units 0x64 0x65 0x6E 24 bitov
deň
Znaky d e ň
Unicode code points 100 101 328
UTF-16 code units 0x0064 0x0065 0x0148 48 bitov
UTF-8 code units 0x64 0x65 0xC588 32 bitov
Základné info o texte
Font
Čo je to znak? – Komplikácia č. 1
Znaky d e n ˇ
Unicode code points 100 101 110 780
Základné info o texte
Kanonické formy
d e n ˇ → d e ň
Základné info o texte
Čo je to znak? – Komplikácia č. 2
V prirodzenom jazyku môže byť tá istá vec raz jeden, inokedy viac znakov
Základné info o texte
ch
https://jazykovaporadna.sme.sk/q/5858/#ixzz5YkHCQGk6
Základné info o texte
ch
Čo je to znak? – Záver
Ďalšie kódovania
I ISO/IEC 8859
I CP 1250
I atď.
PostgreSQL a kódovania
Section 25
Textové typy
Textové typy Znak
Znak
char(n)
I pri práci s nimi sú medzery sprava ignorované (aj keď sme ich zadali
ručne)
Textové typy char(n)
char(n)
char(n)
count
2
Textové typy char(n)
char(n)
varchar(n)
varchar(n)
count
1
Textové typy text
text
Section 26
Práca s textom
Práca s textom Zreťazenie reťazcov
reťazec_1 || reťazec_2
SELECT name,
email,
name || ’ (’ || email || ’)’ AS extended_name
FROM users
Operátor || – NULLy
reťazec_1 || reťazec_2
reťazec || nereťazec
SELECT ’text’ || 68
?column?
text68
Práca s textom Zreťazenie reťazcov
SELECT 32 || 68
Dostaneme chybu
SELECT 32::TEXT || 68
?column?
3268
Práca s textom Dĺžka reťazca
Dĺžka reťazca
length(reťazec)
Dĺžka reťazca
length
30
Práca s textom Úprava reťazcov
Funkcia lower
lower(reťazec)
lower
dvojhrbá ťava
Práca s textom Úprava reťazcov
Funkcia upper
upper(reťazec)
upper
DVOJHRBÁ ŤAVA
Práca s textom Úprava reťazcov
Funkcia position
position(reťazec_1 in reťazec_2)
Funkcia position
position
3
position
0
Práca s textom Úprava reťazcov
Funkcia substring
substring
den dva
Práca s textom Úprava reťazcov
substring
te
length
2
Práca s textom Úprava reťazcov
Funkcia repeat
repeat(reťazec, n)
Funkcia unaccent
unaccent(reťazec)
SELECT unaccent(’článok’)
unaccent
clanok
Práca s textom Odstraňovanie diakritiky
Operátor LIKE
Operátor ILIKE
Operátor SIMILAR TO
Section 27
Fulltextové vyhľadávanie
Fulltextové vyhľadávanie
Fulltextové vyhľadávanie
tsvector
I dátový typ, ktorý predstavuje spracovaný text, nad ktorým môžeme
spustiť fulltextové vyhľadávanie
to_tsvector(text)
I funkcia, ktorá text skonvertuje na tsvector
Fulltextové vyhľadávanie
to_tsvector
’ate’:4 ’cat’:3 ’fat’:2,5 ’rat’:6
Fulltextové vyhľadávanie
tsquery
I dátový typ, ktorý predstavuje dopyt, ktorý chceme nad textom
vyhodnotiť
to_tsquery(dopyt)
I funkcia, ktorá dopyt (text) v špeciálnom tvare skonvertuje na tsquery
I dopyt tvoria slová pospájané:
I booleovskými operátormi: & (AND), | (OR), ! (NOT)
I okruhlými zátvorkami: ( )
I slová sú normalizované
I stop slová sú vyhodené
Fulltextové vyhľadávanie
to_tsquery
’fat’ & ( ’rat’ | ’bird’ )
Fulltextové vyhľadávanie
plainto_tsquery(dopyt)
I funkcia, ktorá čístý text bez operátorov skonvertuje na tsquery
I jednotlivé slová sú vo výsledku pospájané operátorom & (AND)
I slová sú normalizované
I stop slová sú vyhodené
Fulltextové vyhľadávanie
plainto_tsquery
’fat’ & ’rat’ & ’bird’
Fulltextové vyhľadávanie
plainto_tsquery
’fat’ & ’rat’ & ’bird’
Fulltextové vyhľadávanie
tsvector @@ tsquery
tsquery @@ tsvector
?column?
TRUE
?column?
FALSE
Fulltextové vyhľadávanie
Fulltextové vyhľadávanie
SELECT *
FROM articles
WHERE to_tsvector(content)
@@ to_tsquery(’fat & (rat | bird)’)
Fulltextové vyhľadávanie
ts_rank(tsvector, tsquery)
I vracia číslo
I čím je väčšie, tým je dokument relevantnejší pre daný dopyt
Fulltextové vyhľadávanie
SELECT
ts_rank(to_tsvector(’’), to_tsquery(’text’)),
ts_rank(to_tsvector(’text’), to_tsquery(’text’)),
ts_rank(to_tsvector(’text text’), to_tsquery(’text’)),
ts_rank(to_tsvector(’text text text’), to_tsquery(’text’))
Fulltextové vyhľadávanie
SELECT *
FROM articles
WHERE to_tsvector(content)
@@ to_tsquery(’fat & (rat | bird)’)
ORDER BY ts_rank(to_tsvector(content),
to_tsquery(’fat & (rat | bird)’)) DESC
Fulltextové vyhľadávanie
to_tsvector(text)
to_tsquery(text)
plainto_tsquery(text)
to_tsvector(config, text)
to_tsquery(config, text)
plainto_tsquery(config, text)
to_tsvector
’cervez’:2 ’dos’:1 ’favor’:4
Fulltextové vyhľadávanie
to_tsvector to_tsvector
cat’:3 ’dog’:2 ’a’:1 ’cats’:3 ’dog’:2
Práca s dátumom a časom
Section 28
date
I 4 bajty
I od 4717 p.n.l. po 5874897 n.l.
Dátumový literál
DATE ’YYYY-MM-DD’
DATE ’2015-06-17’
Práca s dátumom a časom Dátumové a časové typy podrobne
time
I 8 bajtov
I od 0:00:00 do 24:00:00 vrátane
Práca s dátumom a časom Dátumové a časové typy podrobne
Časový literál
Formát
TIME ’HH:MM:SS.SSSSSS’
TIME ’23:05:00.000001’
Práca s dátumom a časom Dátumové a časové typy podrobne
x
00:00:00
24:00:00
Použitie
schedule
day start end activity
Monday 00:00 02:00 film watching
Monday 22:00 24:00 film watching
Práca s dátumom a časom Dátumové a časové typy podrobne
Dátum s časom
timestamp
I 8 bajtov
I rozsahy rovnako ako pri dátume a čase
I interne reprezentovaný ako počet sekúnd od nejakého pevného času
x
2015-06-17 00:00:00
2015-06-17 00:00:00
interval
I 16 bajtov
I od -178000000 rokov po 178000000 rokov
Práca s dátumom a časom Dátumové a časové typy podrobne
Jednotky
microsecond millisecond second
minute hour day
week month year
decade century millennium
timestamp ± integer → ×
time ± integer → ×
I taký operátor nie je
Práca s dátumom a časom Dátumová a časová aritmetika
I viď dodatok
Práca s dátumom a časom Dátumové a časové funkcie
current_date → date
I vráti aktuálny dátum
localtime → time
I vráti aktuálny čas
localtimestamp → timestamp
I vráti aktuálny dátum a čas
Práca s dátumom a časom Dátumové a časové funkcie
date_part
4
Práca s dátumom a časom Dátumové a časové funkcie
date_trunc
2015-04-01 00:00:00
Práca s dátumom a časom Dátumové a časové funkcie
orders
id time_of_order amount
1 2015-02-05 12:49:00 10
2 2015-02-06 12:50:00 15
week sum
2015-02-02 00:00:00 25
Práca s dátumom a časom Dátumové a časové funkcie
orders
id time_of_order amount
1 2015-02-05 12:49:00 10
2 2015-02-06 12:50:00 15
Section 29
Náhodné čísla
Náhodné čísla
Náhodné čísla
random()
SELECT random()
random
0.216747856233269
Náhodné čísla
Ak chceme, aby boli náhodné čísla celé, musíme ich vhodne konvertovať:
I funkcia floor(x)
I funkcia ceil(x)
I funkcia trunc(x)
I funkcia round(x)
I CAST
Náhodné čísla
floor(x)
ceil(x)
trunc(x)
I odreže desatinnú časť
I trunc(1.5) = 1
I trunc(-1.5) = -1
round(x)
CAST (x AS integer)
I floor a iné funkcie vracajú rovnaký dátový typ ako majú na vstupe
SELECT random() AS x, x * 2 AS y
x y
0.926946882158518 0.789256273768842
Náhodné čísla
SELECT x, x * 2 as y
FROM (SELECT random() AS x) AS tmp
x y
0.239173104055226 0.478346208110452
Náhodné čísla
Section 30
Generovanie dát
Generovanie dát
SELECT
CASE floor(random() * 4)
WHEN 0 THEN ’Mária’ WHEN 1 THEN ’Katarína’
WHEN 2 THEN ’Júlia’ WHEN 3 THEN ’Eliška’
END AS name,
CASE floor(random() * 6)
WHEN 0 THEN ’Priezvisko 1’ WHEN 1 THEN ’Priezvisko 2’
WHEN 2 THEN ’Priezvisko 3’ WHEN 3 THEN ’Priezvisko 4’
WHEN 4 THEN ’Priezvisko 5’ WHEN 5 THEN ’Priezvisko 6’
END AS surname,
floor(random() * 70) + 13 AS age
Funkcia generate_series
generate_series(začiatok, koniec)
Funkcia generate_series
generate_series
-1
0
1
2
Generovanie dát
Funkcia generate_series
i
-1
0
1
2
Generovanie dát
CREATE TABLE AS
CREATE TABLE AS
INSERT INTO
INSERT INTO
Predpokladáme, že tabuľku už máme
Ďalší príklad
SELECT
users.id AS user_id,
tmp.id AS favourite_film_id
FROM
users
CROSS JOIN (SELECT
films.id
FROM films
ORDER BY random()
LIMIT 2) AS tmp
Generovanie dát
SELECT
users.id AS user_id,
tmp.id AS favourite_film_id
FROM
users
CROSS JOIN (SELECT
films.id
FROM films
ORDER BY random()
LIMIT 2) AS tmp
Nie tak úplne
Generovanie dát
Čo očakávame?
user_id favourite_film_id
1 3
1 7
2 61
2 1
3 76
3 6
... ...
Generovanie dát
Čo dostaneme?
user_id favourite_film_id
1 3
1 7
2 3
2 7
3 3
3 7
... ...
Generovanie dát
Prečo?
SELECT
users.id AS user_id,
tmp.id AS favourite_film_id
FROM
users
CROSS JOIN (SELECT
films.id
FROM films
ORDER BY random()
LIMIT 2) AS tmp
Generovanie dát
Prečo?
SELECT
users.id AS user_id,
tmp.id AS favourite_film_id
FROM
users
CROSS JOIN [(2), (7)] as tmp
A ako to opraviť?
A ako to opraviť?
CREATE FUNCTION random_films(x int) RETURNS TABLE (id integer)
LANGUAGE SQL AS
$$
SELECT id FROM films ORDER BY random() LIMIT 2
$$
SELECT
user.id AS user_id,
tmp.id AS favourite_film_id
FROM
users
CROSS JOIN LATERAL random_films(users.id) AS tmp
I volanie funkcie sa odkazuje na riadok tabuľky, takže sa musí zavolať
pre každý riadok
I volanie vlastnej databázovej funkcie systém štandarne nezoptimalizuje
a každé volanie vyhodnotí nanovo
Generovanie dát
x prob
0 5.03
1 10.02
2 9.99
3 10.01
4 10.01
5 10.00
6 9.93
7 9.99
8 10.04
9 9.97
10 5.00
Aktualizovanie štruktúry databázy
Section 31
Čo s produkciou?
Aktualizovanie štruktúry databázy
ALTER TABLE
Aktualizovanie štruktúry databázy
Premenovanie tabuľky
DEFAULT hodnota
NULL
Aktualizovanie štruktúry databázy
Pozor!!!
Čo s dátami?
Aktualizovanie štruktúry databázy
integer → varchar
varchar(2) → varchar(255)
... → ...
Aktualizovanie štruktúry databázy
vals
key : varchar value : varchar
length 20
height 67
vals
key : varchar value : varchar
length 20
height 67
vals
key : varchar value : integer
length 20
height 67
Aktualizovanie štruktúry databázy
users
id : serial name : varchar
1 johny
2 oz
users
id : serial name : varchar
1 johny
2 oz
users
id : serial name : varchar(2)
1 jo
2 oz
Aktualizovanie štruktúry databázy
users
id : serial name : varchar tel_number : integer
1 johny 9393344
2 oz 943423
users
id : serial name : varchar tel_number : varchar
1 johny +4669393344
2 oz +466943423
Aktualizovanie štruktúry databázy
A čo DEFAULT hodnota?
Aktualizovanie štruktúry databázy
kde definícia_integritného_obmedzenia je
[CONSTRAINT názov] UNIQUE (...)
[CONSTRAINT názov] CHECK (...)
[CONSTRAINT názov] PRIMARY KEY (...)
[CONSTRAINT názov] FOREIGN KEY (...) REFERENCES ...
Aktualizovanie štruktúry databázy
ALTER script
Komplexný príklad
films
id : serial
name : varchar
director : varchar
price : numeric
chceme zmeniť na
films
persons
id : serial
name : varchar id : serial
director_id : integer name : varchar
price : numeric
Aktualizovanie štruktúry databázy
Komplexný príklad
Komplexný príklad
Komplexný príklad
Komplexný príklad
Komplexný príklad
Section 32
Skúška
Skúška
Skúška
I na papier
I podobne ako písomka
I 50 bodov
I termíny sú v aise
Section 33
Čo bude na DB2?
Čo bude na DB2?
Predbežný obsah
Predbežný obsah
Koniec
Koniec