CREATE DATABASE ime_baze; -- kreiranje baze USE ime_baze; -- koristenje baze CREATE TABLE student ( -- kreiranje tablice id INTEGER PRIMARY KEY, -- broj, definiranje primarnog ključa jmbag CHAR(10), ime VARCHAR(10), -- string od 10 slova prezime VARCHAR(15), godiste SMALLINT, -- za manje cijele brojeve (-32.7k do 32.7k) visina NUMERIC(5,2), -- (broj ukupnih znamenki, broj decimala od tog broja) npr.-> (5,2) = 157.25 id_grad INTEGER datum DATETIME -- ima jos DATE, TIMESTAMP ... u values se ubacuje kao STR_TO_DATE('04.01.2020.', '%d.%m.%Y.') ); -- postoji jos BLOB, TINYINT ... DROP TABLE ime_tablice; -- brisanje tablice INSERT INTO ime_tablice VALUES (1, '1234567890', 'Marko', 'Marić', '1997', '180.55', 21); -- ubacivanje podataka u red DELETE FROM ime_tablice; -- brisanje svih redaka u tablici grad DELETE FROM ime_tablice WHERE atribut < nešto_iz_tog_atributa; -- izbrisi nesto pod uvijetom ---------------------------------------------------------------------------------------------------------------------------------------------------- Sigma σ SELECT * FROM ime_tablice WHERE atribut > nešto_iz_tog_atributa; npr: SELECT * FROM student WHERE godiste > 2000; -- sigma godiste > 2000 (student) SELECT * FROM student WHERE godiste > 2000 OR prezime = 'Marić'; -- prikazi sve gdje ... SELECT * FROM student WHERE godiste BETWEEN 2000 AND 2005; -- kad trazim izmedju ---------------------------------------------------------------------------------------------------------------------------------------------------- Pi π SELECT atribut1, atribut2 FROM tablica WHERE atribut > nešto_iz_tog_atributa; -- π atribut, atribut (tablica) npr: SELECT id, ime, prezime FROM student WHERE godiste > 2000; -- π id, ime, prezime (student) ---------------------------------------------------------------------------------------------------------------------------------------------------- Dodavanje novog atributa / preimenovanje atributa SELECT atribut1, atribut2, (atribut2 + nešto) AS novo_ime_atributa3 FROM tablica; npr: SELECT id, ime prezime, visina, (visina + 3) AS visina_sa_obucom FROM student; -- visina sa obućom = visina + 3 ---------------------------------------------------------------------------------------------------------------------------------------------------- Kartazijev produkt x SELECT * FROM tablica1, tablica2; npr: SELECT * FROM student, grad; -- kartazijev produkt, student x grad SELECT * FROM student, student AS student2; -- kartazijev produkt student x student SELECT * FROM student, grad WHERE student.id_grad = grad.id; -- povezat studenta sa odgovarajucim gradom (iz kart. produkta) ---------------------------------------------------------------------------------------------------------------------------------------------------- Pronadji neka slova ili nesto unutar podataka u atributu (operator LIKE) SELECT * FROM tablica WHERE atribut LIKE '%on%'; npr: SELECT * FROM student WHERE ime LIKE '%on%'; -- svi studenti gdje unutar imena postoji riječ 'on' '%on'; -- završava na "on" 'on%'; -- počinje na "on" '_on_'; -- srednja dva su "on" ---------------------------------------------------------------------------------------------------------------------------------------------------- Ne pokazuj duple SELECT DISTINCT atribut FROM tablica; SELECT DISTINCT ime FROM student; -- pokazi imena, ali bez da se ponavljaju (mice redak ako su SVE vrijednosti iste u SVIM stupcima) ---------------------------------------------------------------------------------------------------------------------------------------------------- Prikazi sve u atributu velikim slovima UPPER(atribut); npr: SELECT naziv, UPPER(naziv) AS naziv_velika_slova FROM kolegij; -- prikazati sve kolegije sa dodatnom kolonom naziv_velika_slova gdje će nazivi kolegija biti prikazani velikim slovima ---------------------------------------------------------------------------------------------------------------------------------------------------- Pronadji vise necega koji imaju to ili to ili to (operator IN) SELECT * FROM tablica WHERE atribut IN ('vrijednost', 'vrijednost'); npr: SELECT * FROM student WHERE ime IN ('Marko', 'Tea', 'Toni'); -- prikazi sve studente cija imena su ili Marko ili Tea ili Toni ---------------------------------------------------------------------------------------------------------------------------------------------------- Spoji vise vrijednosti (CONCAT) SELECT CONCAT(atribut, 'neki naziv', itd.) AS novo_ime_atributa FROM tablica; -- CONCAT spaja vise vrijednosti u string npr: SELECT *, CONCAT(naziv, '(', sati_nastave, ')') AS info FROM kolegij; -- prikazi sve kolegije sa dodatnim stupcem koji će prikazati naziv kolegija i broj sati nastave u sljedećem obliku: naziv(sati_nastave) ---------------------------------------------------------------------------------------------------------------------------------------------------- Unija ∪ -- spoji u jedan stupac SELECT atribut FROM tablica -- prikazuje sve jedinstvene atribute i spaja u jednan stupac (ne duplikate) UNION -- ako zelim da prikazuje i duplikate onda UNION ALL SELECT atribut FROM tablica; npr: SELECT ime FROM student UNION -- prikazi sva jedinstvena imena i prezimena studenata (rezultat je jedan stupac sa imenima i prezimenima) SELECT prezime FROM student; ---------------------------------------------------------------------------------------------------------------------------------------------------- Presjek ∩ - ne postoji pa moramo simulirat npr: SELECT s1.ime -- prikaži sva imena studenata koja se pojavljuju i kao prezime nekog studenta FROM student AS s1, student AS s2 -- kartazijev WHERE s1.ime = s2.prezime; -- odaberem po cemu trazim ---------------------------------------------------------------------------------------------------------------------------------------------------- Pokazi sve atribute iz neke tablice u kartazijevom produktu SELECT tablica.* ... ---------------------------------------------------------------------------------------------------------------------------------------------------- Dodavanje novog stupca ALTER TABLE tablica ADD COLUMN ime_novog_atributa VRSTA; ALTER TABLE student ADD COLUMN jmbag CHAR(10); -- dodaj novi stupac u tablicu student nazvan jmbag koji mora podržati 10 znakova ---------------------------------------------------------------------------------------------------------------------------------------------------- Sortirati / rasporedi po ORDER BY SELECT * FROM tablica ORDER BY atribut DESC/ASC; -- DESC (silazno) od veceg prema manjem / ASC od manjeg prema vecem (uzlazno) npr: SELECT * FROM video ORDER BY broj_pregleda DESC; SELECT * FROM korisnik ORDER BY prezime DESC, ime ASC; -- za vise, ako ima dva ista npr prezimena ide dalje pa se sortira po imenima. Prvo sortira prezimena ---------------------------------------------------------------------------------------------------------------------------------------------------- AGREGACIJSKE FUNCKIJE γ Pronadji najveci broj / zbroji / minimum / maximum / prosjek SELECT MAX/SUM/MIN/MAX/AVG(atribut) FROM tablica; npr: SELECT MAX(broj_pregleda) FROM video; ---------------------------------------------------------------------------------------------------------------------------------------------------- Broj redaka (COUNT) SELECT COUNT(atribut) FROM tablica; npr: SELECT COUNT(broj_pregleda) FROM video; ---------------------------------------------------------------------------------------------------------------------------------------------------- Grupiranje (GROUP BY) SELECT sta trebam FROM tablica WHERE ... GROUP BY atribut; npr: SELECT v.*, COUNT(*) AS broj_ocjena -- prvo sam sve spojio, i prebrojio kolko sam stvari grupiro FROM video AS v, ocjena AS o WHERE v.id=o.id_video GROUP BY v.id; -- grupiraj po tom atributu, pokaze kolko je istih tih v.id ---------------------------------------------------------------------------------------------------------------------------------------------------- Zelim nesto nakon grupiranja tj. AND za nakon grupiranja (HAVING) npr: SELECT v.*, COUNT(*) AS broj_ocjena FROM video AS v, ocjena AS o WHERE v.id=o.id_video GROUP BY v.id HAVING broj_ocjena =1; ---------------------------------------------------------------------------------------------------------------------------------------------------- Kada zelim nesto "koji nisu", "kojih nema" -- operacija razlike (NOT IN) SELECT * FROM tablica1 WHERE atribut1 NOT IN (SELECT atribut2 FROM tablica2); -- selektiraj iz tablice sve koji nisu u tome trazenom npr: SELECT * -- prikazi sve korisnike koji nisu ocijenili niti jedan video FROM korisnik WHERE id NOT IN (SELECT id_korisnik FROM ocjena); ---------------------------------------------------------------------------------------------------------------------------------------------------- Kad se nesto pojavljuje i tu i tu (u oba) SELECT atribut FROM tablica WHERE atribut2 IN (dohvatim to drugo gdje se ono treba nalazit): npr: SELECT ime FROM korisnik WHERE ime IN (SELECT prezime FROM korisnik); ---------------------------------------------------------------------------------------------------------------------------------------------------- Kolerirani upiti npr: -- prikaži sve video zapise sa dva dodatna stupca: broj pozitivnih i broj negativnih ocjena SELECT *, (SELECT COUNT(*) -- napravim upite koji me zanimaju i povezem sa pravom tablicom da moze sve uzet FROM ocjena WHERE id_video = vanjski_video.id AND ocjena = 'L') AS broj_likeova, (SELECT COUNT(*) FROM ocjena WHERE id_video = vanjski_video.id AND ocjena = 'D') AS broj_dislikeova FROM video AS vanjski_video; -- napravim pravu tablicu "vanjsku" ---------------------------------------------------------------------------------------------------------------------------------------------------- Operacija EXISTS - ne preporuca se, isto ko i NOT IN samo kompliciranije npr: -- prikaži sve video zapise koji nemaju niti jednu ocjenu SELECT * FROM video WHERE NOT EXISTS (SELECT * FROM ocjena WHERE ocjena.id_video = video.id); ---------------------------------------------------------------------------------------------------------------------------------------------------- Operacija ALL -- kada zelis usporedit nesto s nekim atributom koji ima vise redova npr: -- prikaži sve video zapise koji imaju veći broj pregleda nego video zapisi sa naslovima 'Learn Relational Algebra: Part II' i '*** Music Video' SELECT * FROM video WHERE broj_pregleda > ALL ( SELECT broj_pregleda FROM video WHERE naslov = 'Learn Relational Algebra: Part II' OR naslov = '*** Music Video'); ---------------------------------------------------------------------------------------------------------------------------------------------------- Pretvori NULL u 0 -- COALESCE COALESCE (atribut u kojem se pojavljuje NULL, 0); npr: COALESCE(broj_likeova, 0); ****************************************************************** -- JOINOVI -- ****************************************************************** CROSS JOIN -- obicni kartazijev produkt npr. SELECT * -- povezi sve gradanine i zaposlenike FROM gradanin CROSS JOIN zaposlenik; ---------------------------------------------------------------------------------------------------------------------------------------------------- Kada spajam tablicu s tablicom, ali u toj drugoj nema necega -- operacija LEFT OUTER JOIN / RIGHT OUTER JOIN SELECT * FROM tablica AS ime LEFT OUTER JOIN tablica2 AS ime2 ON id = id; npr: -- spajam videe s ocjenama, ali nemaju svi videi ocjenu, ON je kako spajam SELECT * FROM video AS v LEFT OUTER JOIN ocjena AS o ON v.id = o.id_video; npr: -- prikaži sve građane i njihove osobne bankare, uključujući građane koji nemaju osobnog bankara SELECT * FROM gradanin AS g LEFT OUTER JOIN zaposlenik AS Z ON g.id_zaposlenik = z.id; npr: -- prikaži građane i njihove osobne bankare, uključujući bankare koji nisu osobni bankari niti jednom građaninu SELECT * FROM gradanin AS g RIGHT OUTER JOIN zaposlenik AS Z ON g.id_zaposlenik = z.id; ---------------------------------------------------------------------------------------------------------------------------------------------------- Kartazijev produkt s operacijom INNER JOIN SELECT * FROM tablica AS t INNER JOIN tablica2 AS t2 ON t.id = t2.id; npr: -- prikaži građane i njihove osobne bankare SELECT * FROM gradanin AS g INNER JOIN zaposlenik AS Z ON g.id_zaposlenik = z.id; -- ON je uvjet spajanja npr: SELECT * -- kad zelim u kartazijev produkt jos spojit, moze biti vise innera FROM komentar AS k INNER JOIN korisnik AS kr ON k.id_korisnik = kr.id INNER JOIN video AS v ON v.id = k.id_video; ---------------------------------------------------------------------------------------------------------------------------------------------------- FULL OUTER JOIN Radim LEFT OUT JOIN i RIGHT OUTER JOIN te ih spojim unijom (UNION) ---------------------------------------------------------------------------------------------------------------------------------------------------- Spoji tablice po nekom atributu -- Operacija USING npr: SELECT * FROM gradanin LEFT OUTER JOIN zaposlenik USING(prezime); ---------------------------------------------------------------------------------------------------------------------------------------------------- Postavi novu vrijednost / azuriraj polje -- operacija UPDATE UPDATE tablica SET atribut = ...; npr: -- povecaj stanje na tekucem racunu za 20% gradaninu sa imenom 'teo' UPDATE tekuci SET stanje = stanje * 1.2 -- ako zelim vise stvari mijenjat samo dodam zarez i pisem dalje WHERE id_gradanin = (SELECT id FROM gradanin WHERE ime = 'Teo'); ---------------------------------------------------------------------------------------------------------------------------------------------------- Unesi red iz jedne u drugu tablicu Moramo samo pazit da se poklapa, ako se ne poklapa onda selectam samo sta zelim, a u atribut koji nemam stavim nesto npr. ovdje 0.0 npr: -- unesi sve tekuće račune kao štednje građana sa imenom 'Linda' INSERT INTO stednja SELECT id, id_gradanin, broj_racuna, stanje, 0.0 AS nova_kamatna_stopa FROM tekuci WHERE id_gradanin = (SELECT id FROM gradanin WHERE ime = 'Linda'); ---------------------------------------------------------------------------------------------------------------------------------------------------- Dohvati nesto gdje je atribut nula / NULL -- IS NULL, ako treba obrnuto IS NOT NULL SELECT nesto FROM tablica WHERE atribut IS NULL; npr: SELECT * FROM komentar WHERE id_nad_komentar IS NULL; ---------------------------------------------------------------------------------------------------------------------------------------------------- Kada zeli pronac nesto sto ima najmanji npr: -- te onda napravim kartazijev, groupiram i sa HAVING stavim da nadje taj najmanji (2.) SELECT kr.* FROM korisnik AS kr, komentar AS k WHERE kr.id = k.id_korisnik GROUP BY kr.id HAVING COUNT(*) = ( SELECT MIN(broj_komentara) -- prvo pronadjem koliko komentara ima svaki korisnik i uhvatim koji ima najmanje, (1.) FROM( SELECT id_korisnik, COUNT(*) AS broj_komentara FROM komentar GROUP BY id_korisnik ) AS br_kom ); ili mogu limitirati npr: -- pronadjem najmanji grupiranje i prebrojavanjem, poredam od najmanjeg i limitiram na 1 red SELECT kr.*, COUNT(*) FROM korisnik AS kr, komentar AS k WHERE kr.id = k.id_korisnik GROUP BY kr.id ORDER BY COUNT(*) ASC LIMIT 1; ---------------------------------------------------------------------------------------------------------------------------------------------------- Brisanje pod nekim uvjetima ---------------------------------------------------------------------------------------------------------------------------------------------------- Kreiranje pogleda -- CREATE VIEW CREATE VIEW ime AS ... npr: CREATE VIEW gradanin_tekuci AS -- kreiram pogled na to sve (2.) SELECT g.*, SUM(stanje) AS ukupno_stanje_tekuci -- napravim sta trazim (1.) FROM gradanin AS g LEFT JOIN tekuci AS t ON g.id = t.id_gradanin GROUP BY g.id; npr: -- kada zelimo pokazat vise tablica, ali se poklapaju npr. dva ista id-a CREATE VIEW bankar_marina AS SELECT g.*, z.ime AS z_ime, z.prezime AS z_prezime, z.datum_zaposlenja AS z_datum_zaposlenja FROM gradanin AS g INNER JOIN zaposlenik AS z ON g.id_zaposlenik = z.id WHERE z.ime = 'Marina'; ---------------------------------------------------------------------------------------------------------------------------------------------------- INSERT u poglede -- moze kada koristimo SAMO JEDNU tablicu npr: CREATE VIEW ime AS ... INSERT INTO ime VALUES (); ---------------------------------------------------------------------------------------------------------------------------------------------------- WITH CHECK OPTION -- dodaje uvjet ubacivanja u pogled npr: CREATE VIEW gradanin_bez_bankara AS SELECT * FROM gradanin WHERE id_zaposlenik IS NULL WITH CHECK OPTION; -- ne dopusta INSERT novog gradanina koji ima id_zaposlenik NULL ******************************************************************** -- DDL -- ******************************************************************** Zabraniti unos NULL vrijednosti -- NOT NULL npr: CREATE TABLE korisnik ( id INTEGER PRIMARY KEY NOT NULL, email VARCHAR(40) NOT NULL, ime VARCHAR(15) NOT NULL, prezime VARCHAR(20) NOT NULL ); ---------------------------------------------------------------------------------------------------------------------------------------------------- Jedinstvena vrijednost -- UNIQUE npr: -- emailovi korisnika moraju biti jedinstveni CREATE TABLE ime ( id INTEGER PRIMARY KEY, email VARCHAR(40) UNIQUE ); ili kad ima vise atributa koji trebaju bit jedinstveni npr: -- ograniči da korisnik može objaviti samo jedan komentar po videu CREATE TABLE komentar ( id INTEGER PRIMARY KEY, id_video INTEGER, id_korisnik INTEGER, datum DATETIME, sadrzaj VARCHAR(50), id_nad_komentar INTEGER, UNIQUE(id_video, id_komentar) -- ovako napravimo vise jedinstvenih atributa ); ---------------------------------------------------------------------------------------------------------------------------------------------------- Odredjene vrijednosti -- CHECK (uvijet) npr: -- broj pregleda mora biti veći od -1 i manji od 100000 CREATE TABLE ime ( broj_pregleda INTEGER CHECK (broj_pregleda > -1 AND broj_pregleda < 100000), ... ); ---------------------------------------------------------------------------------------------------------------------------------------------------- Popuni s nekom vrijednoscu ako se pri insertu nista ne upise -- DEFAULT vrijednost npr: CREATE TABLE ime ( broj_pregleda INTEGER DEFAULT 0, -- upisat ce se 0 u tablicu, ako ne insertam nista ... ); ---------------------------------------------------------------------------------------------------------------------------------------------------- Da ne mozemo upisat bilo koji id, ako tu uzima strani id -- FOREIGN KEY FOREIGN KEY (atribut) REFERENCES tablica (atribut) npr: CREATE TABLE komentar ( id INTEGER PRIMARY KEY, id_video INTEGER NOT NULL, id_korisnik INTEGER NOT NULL, ... FOREIGN KEY (id_video) REFERENCES video (id), -- kazemo mu da je id_video stvarno id iz tablice video FOREIGN KEY (id_korisnik) REFERENCES korisnik (id) ); ---------------------------------------------------------------------------------------------------------------------------------------------------- Obrisi red i ako je taj red jos negdje povezan u drugoj tablici -- ON DELETE CASCADE npr: CREATE TABLE komentar ( id INTEGER PRIMARY KEY, id_video INTEGER NOT NULL, id_korisnik INTEGER NOT NULL, ... UNIQUE (id_video, id_korisnik), FOREIGN KEY (id_video) REFERENCES video (id) ON DELETE CASCADE, -- u slucaju brisanja obrisat ce video i redove gdje je taj id povezan (ovdje zelimo obrisat video i komentare na tom videu) FOREIGN KEY (id_korisnik) REFERENCES korisnik (id), FOREIGN KEY (id_nad_komentar) REFERENCES komentar (id) ); ---------------------------------------------------------------------------------------------------------------------------------------------------- Samo ispunjavanje -- AUTO_INCREMENT npr: CREATE TABLE video ( id INTEGER PRIMARY KEY AUTO_INCREMENT, -- samo ce ispunit id naslov VARCHAR(40) NOT NULL, broj_pregleda INTEGER NOT NULL DEFAULT 0, video_sadrzaj VARCHAR(20) NOT NULL, ); Pri INSERT-u mozemo: npr: -- izostavimo id i ono ce samo napravit id INSERT INTO video (naslov, broj_pregleda, video_sadrzaj) VALUES ('Formula 1 Australian Grand Prix', 500, 'video1'), ('Learn Relational Algebra: Part II', 30, 'video2'), npr: -- Ili staviti NULL pod id INSERT INTO komentar VALUES (NULL, 1, 3, STR_TO_DATE('04.01.2020.', '%d.%m.%Y.'), 'What happened at 02:00?', NULL), (NULL, 2, 1, STR_TO_DATE('07.01.2020.', '%d.%m.%Y.'), 'What does "sigma" actually do?', NULL), ---------------------------------------------------------------------------------------------------------------------------------------------------- Nek ispise nesto ovisno o -- CASE SELECT *, CASE WHEN atribut = 'nesto' THEN 'nesto' WHEN atribut2 = 'nesto' THEN 'nesto' END AS ime_novog_atributa FROM ... npr: -- prikaži sve ocjene, odgovarajuće korisnike i videe sa dodatnim stupcem 'ocjena_znacenje' gdje će ovisno o ocjeni pisati: L = 'Like', D = 'Dislike' SELECT *, CASE -- te onda dodam CASE (2.) WHEN ocjena = 'L' THEN 'Like' WHEN ocjena = 'D' THEN 'Dislike' ELSE 'Unknown' END AS ocjena_znacenje FROM ocjena AS o -- napravim select (1.) INNER JOIN korisnik AS k on o.id_korisnik = k.id INNER JOIN video AS v ON o.id_video = v.id; npr: -- selektiraj ... i stavi kada je ocjena NULL da je na dnu liste SELECT * FROM ocjena AS o RIGHT OUTER JOIN korisnik AS k ON o.id_korisnik = k.id ORDER BY ( CASE WHEN ocjena IS NULL THEN 'X' -- X je iza D i L sigurno pa smo to stavili ELSE ocjena END ) ASC; ---------------------------------------------------------------------------------------------------------------------------------------------------- Kada zelim pronaci neki po redu npr: -- prikaži video zapis koji je treći po redu prema najvećim brojem pregleda SELECT * FROM video ORDER BY broj_pregleda DESC LIMIT 2, 1; -- LIMIT prva dva i pokazi jedan nakon tog ---------------------------------------------------------------------------------------------------------------------------------------------------- Zaokruzi broj na cjelobrojni broj -- ROUND() Zaokruzi na nizi broj -- FLOOR() Zaokruzi na visi broj -- CEIL () Apsolutni broj -- ABS() npr: SELECT ROUND(AVG(broj_ocjena)) AS avg FROM ( SELECT id_korisnik, COUNT(*) AS broj_ocjena FROM ocjena GROUP BY id_korisnik ) AS br_o; ---------------------------------------------------------------------------------------------------------------------------------------------------- Prikazi mjesec -- MONTH() Prikazii dan -- DAY() Prikazi godinu -- YEAR() Prikazi dan u tjednu -- DAYOFWEEK() Prikazi trenutno vrijeme -- NOW() Prikazi datum toliko unazad -- DATE_SUB(NOW(), INTERVAL broj MONTH/DAY/YEAR) , za unaprijed samo -broj npr: SELECT datum, MONTH(datum), YEAR(datum), DAY(datum) FROM komentar; npr: -- prikazi datume 4 mj. unazad od trenutnog SELECT *, NOW() AS sada, DATE_SUB(NOW(), INTERVAL 4 MONTH) AS 4mj_unazad FROM komentar; ****************************************************************** -- NORMALIZACIJA -- ****************************************************************** - podcrtavamo gdje je PRIMARNI KLJUC (ne smije se ponavljat), a ako se ponavlja onda ne podcrtavamo - ako nakon izdvanja podataka opet imamo ponavljanje, napravimo novu relaciju SUPERKLJUČ - kljuc koji zahtjeva najmanji broj redaka - mora moc pronaci jedinstveni redak Pogledam je li nesto ovisno o necemo i ako je, a to drugo nije superkljuc onda radimo izmjene