Podatkovne baze 1

SQL


Kako do podatkov iz baze


SELECT


SELECT - osnovna struktura

SELECT seznam stolpcev, ki jih želimo videti FROM seznam tabel, kjer bomo podatke našli WHERE pogoji, ki določajo, katere podatke želimo videti

SELECT * FROM knjige 
 WHERE cena > 100.00
 ORDER BY naslov;

SELECT * FROM tabela


SQLiteStudio


SELECT s1, s2 FROM tabPod


SELECT s1, s2 FROM tabPod (2)


SELECT DISTINCT


Primer

Ime Priimek Starost Kraj
Janez Slovenec 42 Kranj
Ivan Slovenec 44 Celje
Peter Slovenec 33 Kranj
Miha Slovenski 12 Celje

</small>

SELECT DISTINCT Kraj FROM t;               -- 2 vrstici
SELECT DISTINCT Priimek, Kraj FROM t;      -- 3 vrstice
SELECT DISTINCT Ime, Priimek, Kraj FROM t; -- 4 vrstice
SELECT Kraj FROM t;                        -- 4 vrstice
SELECT Priimek, Kraj FROM t;               -- 4 vrstice
SELECT Ime, Priimek, Kraj FROM t;          -- 4 vrstice

Poizvedba po določenih podatkih


Izrazi


Urejanje


SELECT - dodatki


SELECT - primer

SELECT name, ROUND(population/1000000) AS prebMilijoni
  FROM world
 WHERE continent IN ('Asia', 'Europe') AND
       name LIKE 'C%';

Enostavna oblika stavka SELECT

SELECT * FROM world;

SELECT name, population FROM world;

SELECT name AS "Ime države" FROM world;

SELECT name AS Ime FROM world
 ORDER BY population DESC;

SELECT DISTINCT continent FROM world;

SELECT 2 FROM world WHERE continent = 'Europe';

SELECT population/area FROM world
 WHERE continent IN ('Europe', 'Asia', 'Africa') AND
       area BETWEEN 100000 AND 1000000;

SELECT name FROM world
 WHERE continent = 'Europe'
 ORDER BY population/area;

Zahtevnejše poizvedbe

S podpoizvedbami


Poizvedbe s podpoizvedbami


Poizvedbe s podpoizvedbami (2)


Poizvedbe s podpoizvedbami (3)

SELECT name FROM world
 WHERE population BETWEEN (
         SELECT population FROM world
          WHERE name = 'Canada'
       ) AND (
         SELECT population FROM world
          WHERE name = 'Algeria'
       );

Omejitve


Primer


WITH


WITH (2)


Združevalne funkcije

Združevalne funkcije (2)


Združevalne funkcije (3)


Zgled


Združevalne funkcije in težave


Združevalne funkcije in težave (2)


Združevalne funkcije in težave (3)


Združevalne funkcije in težave (4)


Še en zgled


Še en zgled (2)


Primerjanje z NULL


In sedaj nekaj zapletenega


Kako dobiti seznam celin


Ustrezna celina


Kombiniranje notranje in zunanje poizvedbe


Kombiniranje notranje in zunanje poizvedbe (2)


Ustrezna celina (2)


Končna rešitev

SELECT name, continent, population FROM world
 WHERE continent IN (
         SELECT continent FROM world AS t1
          WHERE 30000000 > ALL (
                  SELECT population FROM world AS t2
                   WHERE t1.continent = t2.continent
                )
       );

Velike države


Združevalne funkcije in skupine podatkov


GROUP BY

SELECT ... FROM tabela
...
GROUP BY stolpci;

GROUP BY - primer

SELECT ... FROM donacije;
Ime Prispevek
Anja 25
Janez 62
Anja 60
Špela 390
Špela 25

</span>

SELECT ... FROM donacije
 GROUP BY ime;
Ime Prispevek
Anja 25
Anja 60
   
Janez 62
   
Špela 390
Špela 25

</span>

SELECT ... FROM donacije
 GROUP BY prispevek/100;
Ime Prispevek
Anja 25
Anja 60
Janez 62
Špela 25
   
Špela 390

</span> </span>


Primer


Izbor stolpcev

SELECT ime, prispevek FROM donacije GROUP BY ime;

SELECT ime, prispevek FROM donacije GROUP BY prispevek / 100;

Napake

SELECT name, continent, MAX(population) FROM world
 GROUP BY continent;

GROUP BY in WHERE

</span>

</span> </span>


GROUP BY in WHERE (2)

SELECT continent, COUNT(*) AS stevilo FROM world 
 WHERE population >= 160000000
 GROUP BY continent;

continent stevilo
Africa 1
Asia 4
North America 1
South America 1

</span>

</span> </span>


Filtriranje skupin


Filtriranje skupin (2)


GROUP BY in HAVING


Še en zgled


In še en zgled


Preverimo


Popravimo


Več ključev


Zgled


Stikanje tabel

</span>

</span> </span>


Stikanje tabel (2)

Leto Kraj
1896 Atene
1948 London
2004 Atene
2008 Beijing
2012 London
Kraj Država
Atene Grčija
London Velika Britanija
Sydney Avstralija

</span>

</span>

Leto Kraj Država
1896 Atene Grčija
1948 London Velika Britanija
2004 Atene Grčija
2008 Beijing  
2012 London Velika Britanija
  Sydney Avstralija

</span> </span>


SELECT in več tabel


Kartezični produkt


Sklicevanje na stolpce


Stikanje z omejevanjem


Izbor določenih vrednosti


Notranji stik (INNER JOIN)


Zunanji stik (OUTER JOIN)


Druge možnosti stikanja


Več tabel


Stikanje

SELECT title FROM movie
  JOIN casting ON movie.id = movieid
  JOIN actor   ON actorid = actor.id
 WHERE actor.name = 'John Wayne';

Igralci v filmu Velikan


Največje zvezde


Glavni igralci


Seznam filmov z Alom Pacinom


Rešitev

SELECT title, name FROM movie
  JOIN casting ON movie.id = movieid
  JOIN actor   ON actor.id = actorid
 WHERE ord = 1 AND
       name <> 'Al Pacino' AND
       movie.id IN (
         SELECT movieid FROM casting
           JOIN actor ON actor.id = actorid
          WHERE actor.name = 'Al Pacino'
    );
 

Vrstni red izvajanja

SELECT [DISTINCT]                       -- 8
    stolpci, združevalne_funkcije       -- 7
  FROM leva_tabela                      -- 1
[LEFT] JOIN                             -- 3
       desna_tabela ON pogoji_stikanja  -- 2
 WHERE vsebinski_pogoji                 -- 4
 GROUP BY ključi_skupin                 -- 5
HAVING pogoji_skupin                    -- 6
 ORDER BY ključi_urejanja               -- 9
 LIMIT število;                         -- 10

Primer


Poizvedba

SELECT narocnik_id, ime, priimek,
         COUNT(narocilo_id) AS stevilo,
         COALESCE(SUM(kolicina), 0) AS skupna_kolicina
  FROM narocnik
  LEFT OUTER JOIN
       narocilo USING (narocnik_id)
 WHERE priimek = 'Kmetec'
 GROUP BY narocnik_id, ime, priimek
HAVING COALESCE(SUM(kolicina), 0) <= 3
 ORDER BY stevilo;

Stikanje

...
FROM narocnik LEFT OUTER JOIN narocilo USING (narocnik_id)
...

narocnik_id ime priimek narocilo_id kolicina
1 Damjan Kmetec 1 2
1 Damjan Kmetec 2 1
2 Aljaž Kmetec NULL NULL
3 Špela Prezelj 3 1
4 Metka Kmetec 4 4

</span>


Filtriranje

...
WHERE priimek = 'Kmetec'
...

narocnik_id ime priimek narocilo_id kolicina
1 Damjan Kmetec 1 2
1 Damjan Kmetec 2 1
2 Aljaž Kmetec NULL NULL
4 Metka Kmetec 4 4

</span>


Združevanje

...
GROUP BY narocnik_id, ime, priimek
...

narocnik_id ime priimek narocilo_id kolicina
1 Damjan Kmetec 1 2
      2 1
2 Aljaž Kmetec NULL NULL
4 Metka Kmetec 4 4

</span>


Filtriranje skupin

...
HAVING COALESCE(SUM(kolicina), 0) <= 3
...

narocnik_id ime priimek narocilo_id kolicina skupna_kolicina
1 Damjan Kmetec 1 2 3
      2 1  
2 Aljaž Kmetec NULL NULL 0
4 Metka Kmetec 4 4 4

</span>


Izračun stolpcev

SELECT narocnik_id, ime, priimek,
         COUNT(narocilo_id) AS stevilo,
         COALESCE(SUM(kolicina), 0) AS skupna_kolicina
...
narocnik_id ime priimek stevilo skupna_kolicina
1 Damjan Kmetec 2 3
2 Aljaž Kmetec 0 0

Urejanje

...
 ORDER BY stevilo;
narocnik_id ime priimek stevilo skupna_kolicina
2 Aljaž Kmetec 0 0
1 Damjan Kmetec 2 3

Še nekaj primerov


Povprečna ocena in dolžina po žanrih


Filmi z več kot enim režiserjem

SELECT naslov, COUNT(*) AS st_reziserjev
  FROM vloga
  JOIN film ON film = id
 WHERE tip = 'R'
 GROUP BY naslov
HAVING st_reziserjev > 1
 ORDER BY st_reziserjev DESC;

Romantične komedije


Romantične komedije (2)


Igralec in režiser v istem filmu

SELECT naslov, ime FROM film
  JOIN vloga ON film.id = film
  JOIN oseba ON oseba = oseba.id
 GROUP BY film.id, naslov, oseba.id, ime
HAVING COUNT(*) = 2;

Igralec in režiser v istem filmu (2)

WITH reziser AS (
       SELECT * FROM vloga
        WHERE tip = 'R'
     ),
     igralec AS (
       SELECT * FROM vloga
        WHERE tip = 'I'
     )
SELECT naslov, ime FROM reziser
  JOIN igralec USING (oseba, film)
  JOIN film ON film.id = film
  JOIN oseba ON oseba.id = oseba;

Kaj počne ta poizvedba?

SELECT film.*
  FROM pripada AS prvi
  JOIN pripada AS drugi USING (film)
  JOIN film ON id = film
 WHERE prvi.zanr = 4 AND
       drugi.zanr = 8 AND
       oznaka <> 'R'
 ORDER BY film.glasovi DESC;

Ustvarjanje baz

CREATE DATABASE baza;

Ustvarjanje tabel

CREATE TABLE tabela (
  stolpec1 tip
    [PRIMARY KEY]                       -- glavni ključ
    [NOT NULL]                          -- prepovedana vrednost NULL
    [UNIQUE]                            -- enolične vrednosti v stolpcu
    [CHECK (pogoj)]                     -- pogoj, ki mora veljati za stolpec
    [DEFAULT (vrednost)]                -- privzeta vrednost
    [REFERENCES druga_tabela(stolpec)], -- tuji ključ
  [PRIMARY KEY (st1, st2, ...),]        -- glavni ključ iz več stolpcev
  [UNIQUE (st1, st2, ...),]             -- enolične vrednosti v več stolpcih
  [CHECK (pogoj),]                      -- pogoj, ki vključuje več stolpcev
  [FOREIGN KEY (st1, st2, ...)          -- tuji ključ iz več stolpcev
     REFERENCES druga_tabela(s1, s2, ...),]
  ...
);

Podatkovni tipi


Omejitve


Omejitve (2)


Privzete vrednosti


Primer (SQLite)

CREATE TABLE kupec (
  id_kupec        integer  PRIMARY KEY AUTOINCREMENT,
  uporabnisko_ime text     NOT NULL UNIQUE,
  ime             text     NOT NULL,
  priimek         text     NOT NULL,
  naslov          text,
  datum_rojstva   date     CHECK (datum_rojstva < DATETIME('now', '-18 years')),
                           -- kupec mora biti starejši od 18 let
  CHECK (LENGTH(ime) + LENGTH(priimek) <= 30)
);

CREATE TABLE narocilo (
  id_narocilo     integer  PRIMARY KEY AUTOINCREMENT,
  id_kupec        integer  NOT NULL REFERENCES kupec(id_kupec),
  stevilo         integer  DEFAULT (1),
  datum           datetime DEFAULT (DATETIME('now'))
);

Vstavljanje podatkov

INSERT INTO tabela [(stolpec1, stolpec2, ...)]
VALUES (vrednost1, vrednost2, ...), ...;

Vstavljanje izpeljanih podatkov

INSERT INTO tabela [(stolpec1, stolpec2, ...)]
SELECT ...;

Primeri

INSERT INTO kupec (uporabnisko_ime, ime, priimek, datum_rojstva)
VALUES ('janez', 'Janez', 'Novak', '1978-03-24'); -- dobi id_kupec = 1

INSERT INTO kupec (uporabnisko_ime, ime, priimek, datum_rojstva)
VALUES ('micka', 'Micka', 'Kovač', '2008-07-11'); -- napaka!

INSERT INTO kupec (uporabnisko_ime, ime, priimek, datum_rojstva)
VALUES ('micka', 'Micka', 'Kovač', '1998-07-11'); -- dobi id_kupec = 2

INSERT INTO narocilo (id_kupec)
SELECT id_kupec FROM kupec
 WHERE priimek = 'Novak';  -- ena vrstica, dobi id_narocilo = 1

INSERT INTO narocilo (id_kupec, stevilo)
VALUES (1, 3), (2, 4), (2, 2), (3, 6), (1, 5); -- napaka!

INSERT INTO narocilo (id_kupec, stevilo)
VALUES (1, 3), (2, 4), (2, 2), (1, 5); -- dobijo id_narocilo = 2, 3, 4, 5

Spreminjanje obstoječih podatkov

UPDATE tabela
   SET stolpec1 = vrednost1, stolpec2 = vrednost2, ...
 WHERE pogoj;

Brisanje podatkov

DELETE FROM tabela
 WHERE pogoj;

Primeri

UPDATE narocilo
   SET stevilo = stevilo - 1
 WHERE id_kupec = 1;

DELETE FROM narocilo
 WHERE stevilo < 1;

Transakcije


Spremembe in transakcije