You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
SVEUĈILIŠTE U MOSTARU<br />
FAKULTET STROJARSTVA I RAĈUNARSTVA<br />
<strong>BAZE</strong> <strong>PODATAKA</strong> 2<br />
Doc.dr.sc. GORAN KRALJEVIĆ<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 1
Baze podataka 2<br />
Web:<br />
http://<strong>www</strong>2.<strong>fsr</strong>.<strong>ba</strong>/nastava/<strong>ba</strong>ze<br />
Pitanja, primjedbe, dogovor za konzultacije ...<br />
E-mail: goran.kraljevic@hteronet.<strong>ba</strong><br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 2
Uvod u SQL<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 3
SQL<br />
• SQL = Structured Query Language<br />
• SQL je upitni jezik temeljen na relacijskoj algebri i predikatnom<br />
računu.<br />
• SQL se koristi kao programski jezik i interaktivni upitni jezik.<br />
Kao programski jezik može se ugrađivati u jezike treće i četvrte<br />
generacije.<br />
• Zadaća SQL-a je omogućiti definiciju podataka, upravljanje podacima<br />
i provođenje kontrole nad podacima u relacijskoj <strong>ba</strong>zi podataka.<br />
• Proizvođači komercijalnih sustava također ugrađuju i svoje, uglavnom<br />
nestandardne, DDL i DML naredbe.<br />
Ti su nestandardni dijelovi problematični jer programski kod postaje<br />
neprenosiv između različitih SQL sustava, a također se bitno otežava<br />
usaglašavanje oko budućih standarda.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 4
SQL<br />
• DDL (Data Definition Language)<br />
= izrazi za definiranje podataka<br />
̶ CREATE, ALTER, DROP, GRANT, REVOKE ...<br />
• DML (Data Manipulation Language)<br />
= izrazi za upravljanje podacima<br />
̶ SELECT, INSERT, UPDATE, DELETE ...<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 5
SQL<br />
• Primjer SQL naredbe iz DDL dijela jezika (kreiranje tablice mjesto):<br />
CREATE TABLE mjesto<br />
( pbr_mjesta VARCHAR2(5) NOT NULL ,<br />
);<br />
naziv_mjesta VARCHAR2(30) NOT NULL ,<br />
sifra_opcine NUMBER(4)<br />
• Primjer SQL naredbe iz DML dijela jezika (iz tablice mjesto dohvaća sve<br />
n-torke kojima je vrijednost atributa poštanski broj jednaka 88000):<br />
SELECT *<br />
FROM mjesto<br />
WHERE pbr = 88000;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 6
Izvršavanje SQL iskaza (ORACLE server)<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 7
DDL naredbe<br />
Kreiranje tablica<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 8
Kreiranje tablica<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 9
SQL – Kreiranje i brisanje tablica<br />
Kreiranje tablice:<br />
CREATE TABLE ime_tablice<br />
(ime_stupca tip (veličina) (ograničenje),<br />
ime_stupca tip (veličina) (ograničenje),<br />
ime_stupca tip (veličina) (ograničenje),<br />
...);<br />
Brisanje tablice:<br />
DROP TABLE ime_tablice;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 10
Ograniĉenja nad stupcima tablice i nad tablicama ...<br />
• NULL/NOT NULL<br />
• UNIQUE<br />
• PRIMARY KEY<br />
• FOREIGN KEY<br />
• CHECK<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 11
Tipovi podataka (ORACLE)<br />
• VARCHAR2(size)<br />
• CHAR[(size)]<br />
• NUMBER[(p,s)]<br />
• DATE<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 12
Tipovi podataka<br />
Veliki objekti<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 13
PRIMJER – Relacijski model<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 14
SQL – Kreiranje tablica<br />
CREATE TABLE MJESTO<br />
( PBR NUMBER(10) NOT NULL,<br />
);<br />
NAZIV VARCHAR2(40) NOT NULL,<br />
CONSTRAINT mjesto_pk PRIMARY KEY(PBR)<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 15
SQL – Kreiranje tablica<br />
CREATE TABLE OSOBA<br />
( MBR NUMBER(10) NOT NULL,<br />
);<br />
IME VARCHAR2(25) NOT NULL,<br />
PREZIME VARCHAR2(25) NOT NULL,<br />
EMAIL VARCHAR2(40),<br />
PBR NUMBER(10) NOT NULL,<br />
CONSTRAINT oso<strong>ba</strong>_pk PRIMARY KEY(MBR),<br />
CONSTRAINT oso<strong>ba</strong>_mjesto_fk FOREIGN KEY(PBR)<br />
REFERENCES MJESTO(PBR)<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 16
SQL – Izmjena definicije tablice<br />
ALTER TABLE<br />
dodavanje novih atributa<br />
modificiranje postojećih atributa<br />
definiranje default-ne vrijednosti za novi atribut<br />
brisanje atributa<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 17
SQL – ALTER TABLE<br />
Primjeri:<br />
ALTER TABLE oso<strong>ba</strong><br />
DROP COLUMN email;<br />
ALTER TABLE oso<strong>ba</strong><br />
ADD (email VARCHAR2(25));<br />
ALTER TABLE mjesto<br />
MODIFY (naziv VARCHAR2(50));<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 18
DML naredbe<br />
SELECT, INSERT, UPDATE, DELETE<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 19
Najĉešće korišteni DML izrazi<br />
SELECT - Pretraţivanje podataka<br />
INSERT - Upisivanje novih podataka<br />
UPDATE - Promjena vrijednosti podataka<br />
DELETE - Brisanje postojećih podataka<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 20
INSERT – Unos podataka u tablicu<br />
• INSERT INTO ime_tablice (stupac, stupac,…)<br />
VALUES (vrijednost, vrijednost, …);<br />
Primjeri:<br />
• INSERT INTO oso<strong>ba</strong> (mbr, ime, prezime, email)<br />
VALUES (1, 'Ivo', 'Ivic', 'ivo@yahoo.com');<br />
• INSERT INTO oso<strong>ba</strong><br />
VALUES (1, 'Ivo', 'Ivic', 'ivo@yahoo.com');<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 21
INSERT – Unos podataka u tablicu<br />
• INSERT se može koristiti i za kopiranje podataka<br />
iz druge tablice.<br />
Primjer:<br />
• INSERT INTO oso<strong>ba</strong>_2 (mbr, ime, prezime, email)<br />
SELECT mbr, ime, prezime, email<br />
FROM oso<strong>ba</strong>;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 22
UPDATE – Aţuriranje podataka u tablici<br />
• UPDATE ime_tablice [alias] SET<br />
stupac [,stupac…] = {iskaz, podupit}<br />
[WHERE uvjet];<br />
Primjer:<br />
• UPDATE oso<strong>ba</strong> SET email='ivo_ivic@net.hr'<br />
WHERE mbr=1;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 23
DELETE – Brisanje podataka u tablici<br />
• DELETE FROM ime_tablice<br />
[WHERE uvjet];<br />
Primjer:<br />
• DELETE FROM oso<strong>ba</strong><br />
WHERE mbr=2;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 24
SELECT – Selektiranje podataka iz tablice<br />
• SELECT stupac, stupac, stupac, …<br />
FROM ime_tablice<br />
[WHERE uvjet];<br />
Primjeri:<br />
• SELECT mbr, ime, prezime, email<br />
FROM oso<strong>ba</strong>;<br />
• SELECT * FROM oso<strong>ba</strong>;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 25
INSERT – Primjeri<br />
• INSERT INTO mjesto (pbr, naziv)<br />
VALUES (88000, 'Mostar');<br />
• INSERT INTO mjesto (pbr, naziv)<br />
VALUES (88220, 'Široki Brijeg');<br />
• INSERT INTO oso<strong>ba</strong> (mbr, ime, prezime, email, pbr)<br />
VALUES (1, 'Ivo', 'Ivic', 'ivo@net.hr', 88000);<br />
• INSERT INTO oso<strong>ba</strong> (mbr, ime, prezime, pbr)<br />
VALUES (2, 'Mate', 'Matic', 88220);<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 26
INSERT – Primjeri<br />
• INSERT INTO oso<strong>ba</strong> (mbr, ime, prezime, email, pbr)<br />
VALUES (2, 'Pero', 'Peric', 'pero@yahoo.com', 88000);<br />
→ ORA-00001: unique constraint (PC-1.OSOBA_PK) violated<br />
• INSERT INTO oso<strong>ba</strong> (mbr, ime, prezime, email, pbr)<br />
VALUES (3, 'Pero', 'Peric', 'pero@yahoo.com', 90000);<br />
→ ORA-02291: integrity constraint (PC-1.OSOBA_MJESTO_FK)<br />
violated - parent key not found<br />
• INSERT INTO oso<strong>ba</strong> (mbr, ime, email, pbr)<br />
VALUES (3, 'Pero', 'pero@yahoo.com', 88000);<br />
→ ORA-01400: cannot insert NULL into ("OSOBA"."PREZIME")<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 27
UPDATE – Primjeri<br />
• UPDATE mjesto SET pbr=10000<br />
WHERE naziv='Mostar';<br />
→ ORA-02292: integrity constraint (PC-1.OSOBA_MJESTO_FK)<br />
violated - child record found<br />
• UPDATE mjesto SET naziv='Š.Brijeg'<br />
WHERE pbr=88220;<br />
• UPDATE oso<strong>ba</strong> SET email='mate.matic@tel.net.<strong>ba</strong>'<br />
WHERE mbr=2;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 28
DELETE – Primjeri<br />
• DELETE FROM mjesto<br />
WHERE pbr=88000;<br />
→ ORA-02292: integrity constraint (PC-1.OSOBA_MJESTO_FK)<br />
violated - child record found<br />
• DELETE FROM oso<strong>ba</strong><br />
WHERE mbr=1;<br />
• DELETE FROM mjesto<br />
WHERE pbr=88000;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 29
S Q L<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 30
Testna <strong>ba</strong>za (Oracle DBMS)<br />
(Baza je napunjena testnim podacima - koristiti ćemo je na vjeţ<strong>ba</strong>ma za SQL upite ...)<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 31
SELECT – Odabir podataka iz tablice<br />
• SELECT stupci [alias]<br />
FROM ime_tablice [alias]<br />
[WHERE uvjeti za redak]<br />
[GROUP BY stupci]<br />
[HAVING uvjeti za grupu redaka]<br />
[ORDER BY stupci];<br />
Primjer – odabir svih podataka iz tablice djelatnik<br />
• SELECT * FROM djelatnik;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 32
Operatori usporedbe, Logiĉki i SQL operatori<br />
=, >, =,
Primjeri<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE placa > 1000<br />
AND sifra_radmj='IT-PROG';<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE placa BETWEEN 1000 AND 2000;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 34
Primjeri<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE ime LIKE 'A%';<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE ime LIKE '_a%';<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 35
Primjeri<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE placa IN (1000, 2000);<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE placa NOT IN (1000, 2000);<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 36
Primjeri<br />
• SELECT id_djelatnika, ime, prezime, placa, email<br />
FROM djelatnik<br />
WHERE email IS NULL;<br />
• SELECT id_djelatnika, ime, prezime, placa, dodatak<br />
FROM djelatnik<br />
WHERE dodatak IS NOT NULL<br />
AND dodatak 100;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 37
Primjeri<br />
• SELECT id_djelatnika, ime, prezime, placa<br />
FROM djelatnik<br />
WHERE placa < 1000<br />
OR placa > 2000;<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj<br />
FROM djelatnik<br />
WHERE sifra_radmj = 'IT-PROG'<br />
OR sifra_radmj = 'IT-ADM';<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 38
Primjeri<br />
Obratiti pozornost – razlikovati sljedeća 2 upita !<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj, placa<br />
FROM djelatnik<br />
WHERE placa > 1300<br />
AND sifra_radmj = 'IT-PROG'<br />
OR sifra_radmj = 'IT-ADM';<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj, placa<br />
FROM djelatnik<br />
WHERE placa > 1300<br />
AND ( sifra_radmj = 'IT-PROG'<br />
OR sifra_radmj = 'IT-ADM' );<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 39
Agregatne funkcije SQL-a<br />
• ISO standard definira 5 agregatnih funkcija:<br />
- COUNT<br />
- SUM<br />
- AVG<br />
- MIN<br />
- MAX<br />
• Ove funkcije se izvršavaju nad jednim stupcem tablice i<br />
vraćaju jednu vrijednost.<br />
• VAŢNO ! Agregatne funkcije se mogu koristiti samo<br />
u SELECT listi i HAVING iskazu.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 40
Agregatne funkcije SQL-a – Primjeri<br />
• SELECT SUM(placa), AVG(placa), MIN(placa), MAX(placa)<br />
FROM djelatnik;<br />
• SELECT COUNT(*) broj_djelatnika<br />
FROM djelatnik;<br />
• SELECT COUNT (DISTINCT sifra_radmj)<br />
FROM djelatnik;<br />
DISTINCT – eliminira duple vrijednosti<br />
Nema efekta na funkcije MIN i MAX, ali ima na SUM i AVG. Može<br />
se navesti samo jedanput u upitu.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 41
Agregatne funkcije SQL-a – Primjeri<br />
• SELECT ime, prezime<br />
FROM djelatnik<br />
WHERE placa > AVG(placa);<br />
→ ORA-00934: group function is not allowed here<br />
• SELECT ime, prezime, SUM(placa)<br />
FROM djelatnik;<br />
→ ORA-00937: not a single-group group function<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 42
GROUP BY<br />
• Grupiranje se o<strong>ba</strong>vlja tako da se n-torke koje imaju jednake<br />
vrijednosti atributa navedenih u listi za grupiranje,<br />
kombiniraju u zajedničku grupu. Za svaku dobivenu grupu,<br />
u rezultatu se pojavljuje samo jedna n-torka.<br />
• Grupiranje je vrlo korisno u kombinaciji s<br />
agregatnim funkcijama.<br />
Primjer:<br />
• SELECT sifra_radmj, AVG(placa) prosj_placa<br />
FROM djelatnik<br />
GROUP BY sifra_radmj;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 43
GROUP BY<br />
• P R A V I L O !<br />
Bilo koji atribut ili izraz u SELECT listi koji<br />
nije agregatna funkcija mora biti i u<br />
GROUP BY iskazu.<br />
Međutim, dopušteno je u GROUP BY iskazu<br />
koristiti i one atribute koji se ne nalaze u<br />
SELECT listi.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 44
GROUP BY – Primjeri<br />
• SELECT sifra_radmj, AVG(placa) prosj_placa<br />
FROM djelatnik<br />
GROUP BY sifra_radmj;<br />
• SELECT AVG(placa)<br />
FROM djelatnik<br />
GROUP BY sifra_radmj;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 45
GROUP BY – Primjeri<br />
• SELECT sifra_radmj, spol, AVG(placa)<br />
FROM djelatnik<br />
GROUP BY sifra_radmj;<br />
→ ORA-00979: not a GROUP BY expression<br />
• SELECT sifra_radmj, spol, AVG(placa)<br />
FROM djelatnik<br />
GROUP BY sifra_radmj, spol;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 46
GROUP BY – Primjeri<br />
• SELECT AVG(COUNT(*)) prosjek_djel_rm<br />
FROM djelatnik<br />
GROUP BY sifra_radmj;<br />
• SELECT MAX(COUNT(*)) max_djel_rm<br />
FROM djelatnik<br />
GROUP BY sifra_radmj;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 47
HAVING<br />
• Koristi se ako se ţeli specificirati koje grupe tre<strong>ba</strong><br />
prikazati, odnosno, koristi se za restrikciju grupa koje se<br />
prikazuju, tj. za ispitivanje vrijednosti agregatnih funkcija.<br />
• VAŢNO ! WHERE iskaz se ne moţe koristiti za<br />
restrikciju grupa. WHERE se koristi samo za<br />
restrikciju pojedinaĉnih redaka.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 48
WHERE – GROUP BY – HAVING<br />
• WHERE dio naredbe određuje koje n-torke će<br />
formirati grupe.<br />
• GROUP BY lista određuje strukturu grupa tj. po<br />
kojim atributima se o<strong>ba</strong>vlja grupiranje n-torki.<br />
• HAVING dio naredbe određuje koje od nastalih<br />
grupa će biti prihvaćene kao rezultat.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 49
HAVING – Primjeri<br />
• SELECT sifra_radmj radno_mjesto, AVG(placa) prosj_placa<br />
FROM djelatnik<br />
GROUP BY sifra_radmj<br />
HAVING AVG(placa)>1500;<br />
• SELECT sifra_opcine, COUNT(*) broj_dj<br />
FROM djelatnik<br />
GROUP BY sifra_opcine<br />
HAVING COUNT(*)>=3;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 50
ORDER BY<br />
• ASC – uzlazno sortiranje (po default-u)<br />
• DESC – silazno sortiranje<br />
→ ORDER BY iskaz dolazi na kraju SELECT upita.<br />
Primjer:<br />
• SELECT ime, prezime, placa<br />
FROM djelatnik<br />
ORDER BY placa DESC;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 51
Izvršavanje SQL iskaza ...<br />
• Pregled radnih mjesta na kojima radi više od 2 djelatnika s plaćom<br />
većom od 1000 KM.<br />
• SELECT sifra_radmj, COUNT(*) broj_djelatnika<br />
FROM djelatnik<br />
WHERE placa>1000<br />
GROUP BY sifra_radmj<br />
HAVING COUNT(*)>2<br />
ORDER BY 2 desc;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 52
Izvršavanje SQL iskaza ...<br />
• Pregled radnih mjesta na kojima radi više od 2 djelatnika s plaćom<br />
većom od 1000 KM.<br />
ID_DJELATNIKA SIFRA_RADMJ PLACA<br />
1 DIR 4800<br />
2 TAJNIK 1100<br />
100 IT-VOD 2500<br />
101 IT-PROG 1600<br />
102 IT-ADM 1400<br />
103 IT-PROG 1800<br />
104 IT-PROG 1500<br />
105 IT-PROG 1500<br />
106 IT-ADM 1300<br />
107 IT-PROG 1250<br />
108 IT-PROG 1200<br />
109 IT-PROG 1000<br />
110 IT-PROG 800<br />
111 IT-PROG 900<br />
112 IT-ADM 700<br />
113 IT-PROG 1100<br />
114 IT-PROG 950<br />
115 IT-PROG 1350<br />
200 PROD-VOD 2000<br />
201 PROD-KAM 1000<br />
202 PROD-KAM 1400<br />
203 PROD-KAM 1100<br />
204 PROD-KAM 1200<br />
... ... ...<br />
100 IT-VOD 2500<br />
1. 2.<br />
WHERE<br />
placa > 1000<br />
ID_DJELATNIKA SIFRA_RADMJ PLACA<br />
1 DIR 4800<br />
2 TAJNIK 1100<br />
101 IT-PROG 1600<br />
102 IT-ADM 1400<br />
103 IT-PROG 1800<br />
104 IT-PROG 1500<br />
105 IT-PROG 1500<br />
106 IT-ADM 1300<br />
107 IT-PROG 1250<br />
108 IT-PROG 1200<br />
113 IT-PROG 1100<br />
115 IT-PROG 1350<br />
200 PROD-VOD 2000<br />
202 PROD-KAM 1400<br />
203 PROD-KAM 1100<br />
204 PROD-KAM 1200<br />
... ... ...<br />
GROUP BY<br />
sifra_radmj<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 53
Izvršavanje SQL iskaza ...<br />
• Pregled radnih mjesta na kojima radi više od 2 djelatnika s plaćom<br />
većom od 1000 KM.<br />
2. 3.<br />
GROUP BY<br />
sifra_radmj<br />
4.<br />
ORDER BY<br />
2 desc<br />
SIFRA_RADMJ COUNT(*)<br />
PROD-KAM 3<br />
IT-ADM 2<br />
IT-PROG 8<br />
...<br />
SIFRA_RADMJ COUNT(*)<br />
IT-PROG 8<br />
PROD-KAM 3<br />
HAVING<br />
COUNT(*)>2<br />
SIFRA_RADMJ COUNT(*)<br />
PROD-KAM 3<br />
IT-PROG 8<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 54
Osnovne metode spajanja tablica<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 55
Spajanje tablica (ORACLE)<br />
Osnovne metode spajanja tablica:<br />
equi-join<br />
non-equi join<br />
outer join<br />
self join<br />
• Obratiti pozornost ! O<strong>ba</strong>vljanje Kartezijevog produkta<br />
relacija ĉesto je posljedica pogreške programera - kad<br />
se zaboravi navesti uvjet spajanja.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 56
Kartezijev produkt<br />
OSOBA MJESTO<br />
ID IME PBR<br />
1 Pero 88000<br />
2 Mate 88000<br />
3 Ivo 88220<br />
• SELECT id, ime, naziv_mjesta<br />
FROM oso<strong>ba</strong>, mjesto<br />
PBR NAZIV_MJESTA<br />
88000 Mostar<br />
88220 Široki Brijeg<br />
ID IME NAZIV_MJESTA<br />
1 Pero Mostar<br />
2 Mate Mostar<br />
3 Ivo Mostar<br />
1 Pero Široki Brijeg<br />
2 Mate Široki Brijeg<br />
3 Ivo Široki Brijeg<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 57
Osnovna sintaksa spajanja<br />
• SELECT Atribut1, Atribut2, ...<br />
FROM Tablica1, Tablica2, Tablica3, ...<br />
WHERE Uvjet spajanja tablica (FKPK)<br />
AND Uvjet spajanja tablica (FKPK)<br />
...<br />
P R A V I L O !<br />
Broj tablica – 1 = Broj uvjeta spajanja<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 58
equi join<br />
Primjer:<br />
• SELECT id, ime, naziv_mjesta<br />
FROM oso<strong>ba</strong>, mjesto<br />
WHERE oso<strong>ba</strong>.pbr=mjesto.pbr;<br />
OSOBA MJESTO<br />
ID IME PBR<br />
1 Pero 88000<br />
2 Mate 88000<br />
3 Ivo 88220<br />
4 Tomo 88000<br />
5 Marija 88220<br />
PBR NAZIV_MJESTA<br />
88000 Mostar<br />
88220 Široki Brijeg<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 59
equi join<br />
Primjer:<br />
• SELECT id, ime, naziv_mjesta<br />
FROM oso<strong>ba</strong>, mjesto<br />
WHERE oso<strong>ba</strong>.pbr=mjesto.pbr;<br />
Rezultat<br />
upita<br />
ID IME NAZIV_MJESTA<br />
1 Pero Mostar<br />
2 Mate Mostar<br />
3 Ivo Široki Brijeg<br />
4 Tomo Mostar<br />
5 Marija Široki Brijeg<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 60
equi join<br />
Primjeri:<br />
• SELECT d.ime, d.prezime, o.naziv_opcine<br />
FROM djelatnik d, opcina o<br />
WHERE d.sifra_opcine=o.sifra_opcine;<br />
• SELECT d.ime, d.prezime, d.email, d.placa,<br />
rm.naziv_radmj, o.naziv_odjela<br />
FROM djelatnik d, radno_mjesto rm, odjel o<br />
WHERE d.sifra_radmj=rm.sifra_radmj<br />
AND rm.sifra_odjela=o.sifra_odjela<br />
AND dodatak is not null;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 61
outer join<br />
Primjer:<br />
• SELECT id, ime, naziv_mjesta<br />
FROM oso<strong>ba</strong>, mjesto<br />
WHERE oso<strong>ba</strong>.pbr=mjesto.pbr;<br />
OSOBA MJESTO<br />
ID IME PBR<br />
1 Pero 88000<br />
2 Mate 88000<br />
3 Ivo 88220<br />
4 Tomo 88000<br />
5 Marija NULL<br />
PBR NAZIV_MJESTA<br />
88000 Mostar<br />
88220 Široki Brijeg<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 62<br />
?
outer join<br />
• SELECT id, ime, naziv_mjesta<br />
FROM oso<strong>ba</strong>, mjesto<br />
WHERE oso<strong>ba</strong>.pbr=mjesto.pbr;<br />
• SELECT id, ime, naziv_mjesta<br />
FROM oso<strong>ba</strong>, mjesto<br />
WHERE oso<strong>ba</strong>.pbr=mjesto.pbr(+);<br />
ID IME NAZIV_MJESTA<br />
1 Pero Mostar<br />
2 Mate Mostar<br />
3 Ivo Široki Brijeg<br />
4 Tomo Mostar<br />
ID IME NAZIV_MJESTA<br />
1 Pero Mostar<br />
2 Mate Mostar<br />
3 Ivo Široki Brijeg<br />
4 Tomo Mostar<br />
5 Marija<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 63
outer join<br />
Primjer:<br />
• SELECT d.id_djelatnika, d.ime, d.prezime, d.placa,<br />
rm.naziv_radmj<br />
FROM djelatnik d, radno_mjesto rm<br />
WHERE d.sifra_radmj=rm.sifra_radmj<br />
AND placa>2000;<br />
• SELECT d.id_djelatnika, d.ime, d.prezime, d.placa,<br />
rm.naziv_radmj, o.naziv_odjela<br />
FROM djelatnik d, radno_mjesto rm, odjel o<br />
WHERE d.sifra_radmj=rm.sifra_radmj<br />
AND rm.sifra_odjela=o.sifra_odjela (+)<br />
AND placa>2000;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 64
self join<br />
Primjer:<br />
• SELECT a.id, a.ime ime_dj, b.ime ime_sefa<br />
FROM oso<strong>ba</strong> a, oso<strong>ba</strong> b<br />
WHERE a.id_sefa=b.id;<br />
OSOBA<br />
ID IME ID_SEFA<br />
1 Pero NULL<br />
2 Mate 1<br />
3 Ivo 1<br />
4 Tomo 1<br />
5 Marija 3<br />
ID IME_DJ IME_SEFA<br />
2 Mate Pero<br />
3 Ivo Pero<br />
4 Tomo Pero<br />
5 Marija Ivo<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 65
self join<br />
Primjer:<br />
• SELECT d1.ime || ' ' || d1.prezime djelatnik, d1.placa,<br />
d1.ime || ' ' || d2.prezime šef, d2.placa<br />
FROM djelatnik d1, djelatnik d2<br />
WHERE d1.id_sefa=d2.id_djelatnika<br />
AND d1.placa > d2.placa;<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 66
SQL podupiti<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 67
Podupiti<br />
SELECT ...<br />
FROM ...<br />
WHERE ...<br />
( SELECT ...<br />
FROM ...<br />
WHERE ... )<br />
Podupit<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 68
Korištenje podupita<br />
Primjer:<br />
• SELECT ime, prezime, placa<br />
FROM djelatnik<br />
WHERE placa ><br />
1800<br />
( SELECT placa<br />
FROM djelatnik<br />
WHERE ime = 'Ernest' );<br />
• U ovom primjeru «unutarnji» SELECT iskaz (PODUPIT) vraća plaću<br />
djelatnika po imenu Ernest.<br />
• «Vanjski» SELECT iskaz koristi taj rezultat «unutarnjeg» upita da bi<br />
prikazao sve djelatnike koji zarađuju više od tog iznosa.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 69
Tipovi podupita<br />
• Podupiti koji vraćaju jedan redak<br />
Operatori: =, >, =,
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi djelatnike ĉije radno mjesto je isto kao i djelatnika 101.<br />
• SELECT ime, prezime, sifra_radmj<br />
FROM djelatnik<br />
WHERE sifra_radmj =<br />
IT-PROG<br />
( SELECT sifra_radmj<br />
FROM djelatnik<br />
WHERE id_djelatnika = 101 );<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 71
Podupiti – Primjer korištenja agregatnih funkcija<br />
Primjer:<br />
• Prikaţi sve djelatnike (ime, prezime, datum zaposlenja, plaća)<br />
ĉija plaća je veća od prosjeĉne plaće u poduzeću.<br />
• SELECT ime, prezime, datum_zaposlenja, placa<br />
FROM djelatnik<br />
WHERE placa ><br />
( SELECT AVG (placa)<br />
);<br />
1.450<br />
FROM djelatnik<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 72
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi djelatnike ĉije radno mjesto je isto kao i djelatnika 101<br />
i ĉija plaća je veća od plaće djelatnike 2.<br />
• SELECT ime, prezime, sifra_radmj, placa<br />
FROM djelatnik<br />
WHERE sifra_radmj = ( SELECT sifra_radmj<br />
FROM djelatnik<br />
AND placa > ( SELECT placa<br />
WHERE id_djelatnika = 101 )<br />
FROM djelatnik<br />
WHERE id_djelatnika = 2 );<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 73
Podupiti – Primjer korištenja podupita u HAVING dijelu iskaza<br />
Primjer:<br />
• SELECT sifra_radmj, AVG (placa)<br />
FROM djelatnik<br />
GROUP BY sifra_radmj<br />
HAVING AVG (placa) ><br />
( SELECT AVG(placa)<br />
FROM djelatnik<br />
WHERE sifra_radmj='IT-PROG');<br />
• Podupit se moţe koristiti ne samo u WHERE dijelu SELECT<br />
iskaza, nego i u HAVING dijelu iskaza. Prvo se izvršava podupit,<br />
a zatim se rezultat podupita vraća u HAVING dio vanjskog upita.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 74
Podupiti – Primjeri najĉešćih pogrešaka<br />
GREŠKA ! Podupit ne vraća niti jedan redak.<br />
Primjer:<br />
• SELECT ime, prezime, sifra_radmj<br />
FROM djelatnik<br />
WHERE sifra_radmj =<br />
( SELECT sifra_radmj<br />
FROM djelatnik<br />
WHERE prezime='Crnjac' );<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 75
Podupiti – Primjeri najĉešćih pogrešaka<br />
GREŠKA ! Podupit vraća više od jednog retka, a koristi se<br />
operator jednakosti (=).<br />
Primjer:<br />
• SELECT id_djelatnika, ime, prezime<br />
FROM djelatnik<br />
WHERE placa =<br />
( SELECT MIN(placa)<br />
FROM djelatnik<br />
GROUP BY sifra_radmj );<br />
→ ORA-01427: single-row subquery returns more than one row<br />
• Da bi ispravili grešku u gornjem upitu operator (=) moţemo<br />
promijeniti u operator (IN).<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 76
Podupiti koji vraćaju više od jednog retka<br />
IN operator<br />
Primjer:<br />
• SELECT ime, prezime, placa, sifra_radmj<br />
FROM djelatnik<br />
WHERE placa IN<br />
( SELECT MIN(placa)<br />
FROM djelatnik d, radno_mjesto rm, odjel o<br />
WHERE d.sifra_radmj=rm.sifra_radmj<br />
AND rm.sifra_odjela=o.sifra_odjela<br />
GROUP BY o.sifra_odjela );<br />
• Nakon izvršavanja podupita, SUBP (npr. Oracle) će ovako vidjeti<br />
vanjski upit ...<br />
• SELECT ime, prezime, placa, sifra_radmj FROM djelatnik<br />
WHERE placa IN (700,900,1000,1200);<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 77
Podupiti koji vraćaju više od jednog retka<br />
ANY i ALL operator<br />
< ANY = manje od maximuma<br />
> ANY = više od minimuma<br />
< ALL = manje od minimuma<br />
> ALL = više od maximuma<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 78
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi djelatnike koji nisu IT programeri i ĉija plaća je niţa od<br />
plaće nekog od IT programera.<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj, placa<br />
FROM djelatnik<br />
WHERE placa < ANY<br />
( SELECT placa<br />
FROM djelatnik<br />
AND sifra_radmj 'IT-PROG' ;<br />
WHERE sifra_radmj = 'IT-PROG' )<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 79
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi djelatnike koji nisu na radnom mjestu PROD-KAM i ĉija<br />
plaća je niţa od plaće svih djelatnika na radnom mjestu PROD-KAM.<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj, placa<br />
FROM djelatnik<br />
WHERE placa < ALL<br />
( SELECT placa<br />
FROM djelatnik<br />
AND sifra_radmj 'PROD-KAM' ;<br />
WHERE sifra_radmj = 'PROD-KAM' )<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 80
Korelacijski podupiti<br />
uzima se kandidat red<br />
iz vanjskog upita<br />
izvršava se unutarnji upit<br />
koristeći podatke iz<br />
kandidat reda<br />
vrijednosti iz unutarnjeg upita<br />
se koriste da se kandidat red<br />
kvalificira ili diskvalificira<br />
• Podupit (unutarnji upit) se izvršava jedanput za svaki redak iz<br />
vanjskog upita.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 81
Korelacijski podupiti<br />
Primjer:<br />
• Prikaţi sve djelatnike koji zaraĊuju više od prosjeĉne plaće u<br />
njihovom odjelu.<br />
• SELECT ime, prezime, d.sifra_radmj, placa<br />
FROM djelatnik d, radno_mjesto vanjski_rm<br />
WHERE d.sifra_radmj=vanjski_rm.sifra_radmj<br />
AND placa > ( SELECT AVG(placa)<br />
FROM djelatnik d, radno_mjesto rm<br />
WHERE d.sifra_radmj=rm.sifra_radmj<br />
AND rm.sifra_odjela =<br />
vanjski_rm.sifra_odjela );<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 82
EXISTS operator<br />
• EXISTS operator testira postojanje redaka u rezultatu<br />
podupita:<br />
– ako podupit vrati <strong>ba</strong>r jedan redak operator EXISTS će<br />
vratiti TRUE.<br />
– ako podupit ne vrati niti jedan redak operator EXISTS će<br />
vratiti FALSE.<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 83
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi sve djelatnike koji imaju <strong>ba</strong>r jednu osobu koja im je<br />
“podreĊena”.<br />
a) korištenjem EXISTS operatora<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj<br />
FROM djelatnik d<br />
WHERE EXISTS (<br />
SELECT 'X'<br />
FROM djelatnik<br />
WHERE id_sefa=d.id_djelatnika<br />
);<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 84
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi sve djelatnike koji imaju <strong>ba</strong>r jednu osobu koja im je<br />
“podreĊena”.<br />
b) korištenjem IN operatora<br />
• SELECT id_djelatnika, ime, prezime, sifra_radmj<br />
FROM djelatnik<br />
WHERE id_djelatnika IN (<br />
SELECT id_sefa<br />
FROM djelatnik<br />
WHERE id_sefa IS NOT NULL<br />
);<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 85
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi općine u kojima ne ţivi niti jedan djelatnik poduzeća.<br />
a) korištenjem NOT EXISTS operatora<br />
• SELECT sifra_opcine, naziv_opcine<br />
FROM opcina o<br />
WHERE NOT EXISTS (<br />
SELECT 'X'<br />
FROM djelatnik<br />
WHERE sifra_opcine=o.sifra_opcine<br />
);<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 86
Podupiti – Primjer<br />
Primjer:<br />
• Prikaţi općine u kojima ne ţivi niti jedan djelatnik poduzeća.<br />
b) korištenjem NOT IN operatora<br />
• SELECT sifra_opcine, naziv_opcine<br />
FROM opcina<br />
WHERE sifra_opcine NOT IN<br />
( SELECT sifra_opcine<br />
FROM djelatnik );<br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 87
Baze podataka 2<br />
Web:<br />
http://<strong>www</strong>2.<strong>fsr</strong>.<strong>ba</strong>/nastava/<strong>ba</strong>ze<br />
Pitanja, primjedbe, dogovor za konzultacije ...<br />
E-mail: goran.kraljevic@hteronet.<strong>ba</strong><br />
Ak.god. 2012/2013 <strong>BAZE</strong> <strong>PODATAKA</strong> 2 88