45
(a)SQL Uvod v MySQL Pripravil: Boštjan Cigan

(a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

(a)SQL Uvod v MySQL

Pripravil: Boštjan Cigan

Page 2: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

2

(a)SQL FRI

Edition

A) UVOD

To skripto sem najprej pisal za lastne potrebe, da bi malce ponovil osnove jezika SQL (ki sem jih med leti obiskovanja študija ţe krepko pozabil). Ker pa večino stvari, ki jih študentje napišejo (od izpiskov, plonkcev - listov A4 formata, ki jih imamo lahko na izpitu – hvala Anchy) priromajo na forum, sem se odločil da tudi sam to skripto prepišem v drugačen način in objavim. Upam da bo v pomoč vsem, ki se z jezikom SQL še niso srečali in bi se radi še malce praktično pozabavali na domačih računalnikih. MySQL sem uporabil zaradi njegove odprtokodnosti (nimam nič proti Oraclu), sem pa pri pisanju karseda poskušal upoštevati standardni jezik, da bi ukazi delovali tudi na Oraclu. Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako da so pripombe, popravki dobrodošli na mojemu email naslov: [email protected] Vsem bralcem ţelim obilico sreče pri izpitu iz Podatkovnih Baz 1 (kolegom iz informatike) in Osnove Podatkovnih Baz. Boštjan

Page 3: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

3

(a)SQL FRI

Edition

B) PREGLED POGLAVIJ Prvo poglavje: Namestitev

Nameščanje paketa MySQL Drugo poglavje: Osnovna uporaba

Prijava v MySQL Prikaz podatkovnih baz

Ustvarjanje baze Brisanje baze Ustvarjanje tabele Uporaba baze Ustvarjanje tabele, pregled tabele, spreminjanje tabele z ukazom alter

Tretje poglavje: Podatkovni tipi

Pregled osnovnih podatkovnih tipov Splošen primer uporabe podatkovnih tipov

Četrto poglavje: Osnovno delo s tabelami

Uporaba insert, select, where, from stavka Operatorji not, between, in, or, and, limit, distinct Spreminjanje podatkov v bazi, uporaba update stavka Brisanje podatkov v bazi, uporaba delete stavka Uporaba concat, zdruţevanje stolpcev

Pregled dela z datumi Peto poglavje: Aritmetika

Izračun povprečja vrednosti, iskanje minimalne in maksimalne vrednosti Uporaba count (štetje vrstic)

Osnoven pregled aritmetičnih izrazov Šesto poglavje: Delo nad množicami tabel

Kreiranje treh tabel Uporaba in namen primarnih ključev in tujih ključev

Razširjen stavek select, uporaba group, having Uporaba poizvedb na večih tabelah hkrati Gnezdenje SQL stavkov

Sedmo poglavje: MySQL Query Browser

Namestitev MySQL Gui Tools Osnovna uporaba MySQL Query Browser

Page 4: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

4

(a)SQL FRI

Edition

1. NAMESTITEV Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe s winning. – Rich Cook

Najprej bomo MySQL namestili. S strani http://dev.mysql.com/downloads/mysql/5.1.html#downloads si potegnite namestitveno datoteko (izberite drugi paket - Windows ZIP/Setup.EXE (x86)). Datoteko razpakirajte in poţenite setup.exe.

Najprej se izvede namestitev datotek. Izberite »Custom«, potem izberite polno namestitev, na koncu pa izberite »Configute MySQL Server now«. Odprlo se bo novo okno. Kliknite »Next« in izberite »Standard configuration«. Obkljukajte »Install as Windows Service«, nujno pa obkljukajte tudi »Include BIN directory in Windows PATH«. S tem bo inštalacija samodejno poskrbela za namestitev spremenljivke path, da bodo ukazi MySQLa avtomatsko dostopni iz kateregakoli direktorija. Izberite »Next« in vpišite vaše ţeleno geslo za uporabnika »root«, ki je v bistvu administrator. Kliknite »Next« in »Execute« in če bo vse po sreči, se vam bo izpisalo, da je bila namestitev uspešno izvedena.

Page 5: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

5

(a)SQL FRI

Edition

Page 6: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

6

(a)SQL FRI

Edition

2. OSNOVNA UPORABA Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody and expert painter. – Eric Raymond Najprej bomo pregledali nekaj osnovnih MySQL ukazov, ki nam bodo koristili pri nadaljnemu delu z bazo. Zaţenite komandno vrstico (Start->Zaţeni, vtipkajte cmd in pritisnite enter). Pojavila se bo dos lupina. Vanjo vpišite sledeč ukaz: mysql -u root -p

S tem se bomo prijavili v MySQL. Stisnite enter in vpišite vaše root geslo (geslo ki ste si ga izbrali pri namestitvi). Če imamo več uporabnikov, se lahko prijavimo tudi pod drugim imenom, splošna uporaba tega ukaza bi bila: mysql -u <ime uporabnika> -p

C:\Documents and Settings\Boštjan>mysql -u root -p

Enter password: *********

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.1.30-community MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

Page 7: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

7

(a)SQL FRI

Edition

Sedaj se nam je lupina spremenila. Vanjo bomo lahko pisali ukaze za delo z bazo. Če se ţelimo iz baze odjaviti, to preprosto storimo takole: mysql> exit

Ob izvedbi se nam bi izpisalo tole:

mysql> exit

Bye

MySQL je še tako prijazen, da se od uporabnika ob odjavi poslovi. Alternativen ukaz za odjavo in izhod je tudi ukaz quit. Če ţelimo, da MySQL pod procesi ugasnemo, moramo v dos konzolo vpisati sledeč ukaz: net stop mysql

Ta ukaz ubije proces mysqld. Za ponoven »zagon« MySQLa moramo v komandno vrstico vpisati net start mysql

Ponovno zaţenite MySQL (če ste se z ukazi poigrali) in se prijavite kot root. Vpišite ukaz show databases (s podpičjem na koncu) in stisnite enter. Izpisalo se vam bo sledeče: mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| test |

+--------------------+

3 rows in set (0.06 sec)

MySQL je izpisal baze, ki so trenutno ustvarjene. Trenutno so ustvarjene tri (privzeto ob namestitvi), mi si bomo pa za potrebe učenja ustvarili novo. To lahko storimo z ukazom create database <ime baze>. mysql> create database vaje;

Query OK, 1 row affected (0.00 sec)

Če sedaj uporabimo ukaz show databases, bi nam MySQL moral izpisati sledeče:

Page 8: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

8

(a)SQL FRI

Edition

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| test |

| vaje |

+--------------------+

4 rows in set (0.00 sec)

Opazimo lahko, da je naša baza bila uspešno ustvarjena. Pa dajmo za potrebe našega naslednjega ukaza ustvariti še eno bazo in sicer vaje2. mysql> create database vaje2;

Query OK, 1 row affected (0.02 sec)

Stanje po ukazu show databases bi moralo biti sledeče:

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| test |

| vaje |

| vaje2 |

+--------------------+

5 rows in set (0.00 sec)

Kako pa bazo izbrisati? To lahko storimo z ukazom drop database <ime baze>. mysql> drop database vaje2;

Query OK, 0 rows affected (0.00 sec)

Če zopet poţenemo ukaz show databases bi morali imeti prejšnjo stanje. mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| test |

| vaje |

+--------------------+

4 rows in set (0.00 sec)

Baze so namenjene hranjenju podatkov. Podatke pa hranimo s pomočjo tabel. Če ţelimo MySQLu povedati s katero bazo bomo delali, uporabimo ukaz use <ime baze> (v našem primeru je to baza vaje). mysql> use vaje;

Database changed

Page 9: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

9

(a)SQL FRI

Edition

MySQL nam bo sporočil database changed, kar pomeni da bomo obdelovali drugo bazo. Sedaj ko MySQL ve, katero bazo obdelujemo, mu lahko rečemo naj ustvari tabelo v tej bazi. To lahko naredimo s pomočjo ukaza create table, osnovna sintaksa bi pa izgledala nekako takole: CREATE TABLE <ime tabele>

(

<primarni ključ>, -- Primarni ključ lahko določimo ali ga pa ne

<ime stolpca> <tip>,

<ime stolpca 2> <tip>,

<ime stolpca 3> <tip>,

<ime stolpca 4> <tip>,

...

<ime stolpca n> <tip>

);

Da bo vse skupaj laţje razumljivo, si bomo to pogledali na primeru. Ustvarili bomo tabelo podatkov, v kateremu bomo hranili imena in priimke študentov Fakultete za računalništvo in informatiko, letnik ki ga obiskujejo in smer (uni, vss, isrm). mysql> CREATE TABLE studenti

-> (

-> id_studenta int unsigned not null auto_increment primary key,

-> st_ime varchar(20),

-> st_priimek varchar(20),

-> letnik int,

-> smer varchar(5)

-> );

Query OK, 0 rows affected (0.19 sec)

Za primarni ključ smo pri nas uporabili kar vrednost int, ki se avtomatsko povečuje (vrednost auto_increment) ob vsakemu novemu vpisu. Kot smo opazili, če stiskamo enter brez da bi uporabili ;, nas MySQL da v novo vrstico in čaka da dokončamo našo poizvedbo ali ukaz z ;. Sedaj je MySQL za nas ustvaril tabelo studenti. Pri MySQLu ukaze ločimo z vejico, najprej napišemo ime stolpca, potem pa napišemo podatkovni tip, ki se bo nahajal v tem stolpcu. S pomočjo ukaza varchar(stevilo) pa smo omejili število črk, ki jih lahko vpišemo v ta podatek. Vprašanje, ki si ga lahko zastavimo je, kako pa pogledati strukturo določene tabele? To lahko storimo z ukazom describe <ime tabele>, ki nam ob izvedbi izpiše strukturo tabele, ki smo jo podali. mysql> describe studenti;

+-------------+------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+------------------+------+-----+---------+----------------+

| id_studenta | int(10) unsigned | NO | PRI | NULL | auto_increment |

| st_ime | varchar(20) | YES | | NULL | |

| st_priimek | varchar(20) | YES | | NULL | |

| letnik | int(11) | YES | | NULL | |

| smer | varchar(5) | YES | | NULL | |

+-------------+------------------+------+-----+---------+----------------+

5 rows in set (0.33 sec)

Page 10: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

10

(a)SQL FRI

Edition

Kako pa izbrisati določeno tabelo? Obstaja podoben ukaz kot za baze. V SQL komandno vrstico vpišemo drop table <ime tabele>. Če to naredimo na naši tabeli student, bi se moralo narediti sledeče: mysql> drop table studenti;

Query OK, 0 rows affected (0.05 sec)

Kaj pa če bi našo tabelo študentov ţeleli preimenovati v tabelo dijakov? Za to bi uporabili ukaz alter z navezo z rename. mysql> ALTER TABLE studenti RENAME dijaki;

Query OK, 0 rows affected (0.22 sec)

mysql> SHOW TABLES;

+----------------+

| Tables_in_vaje |

+----------------+

| dijaki |

+----------------+

1 row in set (0.08 sec)

S pomočjo alter lahko tudi brišemo ali dodajamo stolpce. Dajmo najprej našo tabelo preimenovati nazaj v studenti, potem si pa poglejmo primer dodajanja in odstranjevanja stolpcev. mysql> ALTER TABLE dijaki RENAME studenti;

Query OK, 0 rows affected (0.09 sec)

mysql> ALTER TABLE studenti ADD d_rojstva varchar(20);

Query OK, 0 rows affected (0.36 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> DESCRIBE studenti;

+-------------+------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+------------------+------+-----+---------+----------------+

| id_studenta | int(10) unsigned | NO | PRI | NULL | auto_increment |

| st_ime | varchar(20) | YES | | NULL | |

| st_priimek | varchar(20) | YES | | NULL | |

| letnik | int(11) | YES | | NULL | |

| smer | varchar(5) | YES | | NULL | |

| d_rojstva | varchar(20) | YES | | NULL | |

+-------------+------------------+------+-----+---------+----------------+

6 rows in set (0.14 sec)

Kot vidimo je splošna uporaba ukaza sledeča:

ALTER TABLE <ime tabele> ADD <ime stolpca> <tip>;

Dajmo še pogledati, kako bi spremenili kakšen stolpec. Na primer, da smo našli študenta, ki ima več kot 20 črk v imenu. To bi potem naredili takole:

Page 11: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

11

(a)SQL FRI

Edition

mysql> ALTER TABLE studenti CHANGE st_ime stu_ime varchar(25);

Query OK, 0 rows affected (0.20 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> DESCRIBE studenti;

+-------------+------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+------------------+------+-----+---------+----------------+

| id_studenta | int(10) unsigned | NO | PRI | NULL | auto_increment |

| stu_ime | varchar(25) | YES | | NULL | |

| st_priimek | varchar(20) | YES | | NULL | |

| letnik | int(11) | YES | | NULL | |

| smer | varchar(5) | YES | | NULL | |

| d_rojstva | varchar(20) | YES | | NULL | |

+-------------+------------------+------+-----+---------+----------------+

6 rows in set (0.05 sec)

Splošno ukaz potem izgleda takole:

ALTER TABLE <ime tabele> CHANGE <ime stolpca> <novo ime> <tip>;

Dajmo sedaj še izbrisati naš novonastali stolpec d_rojstva. mysql> ALTER TABLE studenti DROP d_rojstva;

Query OK, 0 rows affected (0.63 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> DESCRIBE studenti;

+-------------+------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+------------------+------+-----+---------+----------------+

| id_studenta | int(10) unsigned | NO | PRI | NULL | auto_increment |

| stu_ime | varchar(25) | YES | | NULL | |

| st_priimek | varchar(20) | YES | | NULL | |

| letnik | int(11) | YES | | NULL | |

| smer | varchar(5) | YES | | NULL | |

+-------------+------------------+------+-----+---------+----------------+

5 rows in set (0.00 sec)

Sedaj pa še preimenujmo stu_ime nazaj v st_ime. mysql> ALTER TABLE studenti CHANGE stu_ime st_ime varchar(20);

Query OK, 0 rows affected (0.25 sec)

Records: 0 Duplicates: 0 Warnings: 0

Mogoče lahko pogledamo še ukaz, ki bi tudi bil vreden omembe v tem poglavju, je sprememba gesla. Geslo lahko spremenimo, da vpišemo: mysql> set password = password("novogeslo");

Query OK, 0 rows affected (0.06 sec)

Page 12: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

12

(a)SQL FRI

Edition

3. PODATKOVNI TIPI Programming is like sex. One mistake and you have to support it for the rest of your life. – Michael Sinz V prejšnjemu poglavju smo na koncu ustvarili tabelo študentov, ki je vsebovala imena, priimke, letnik in smer. Preden nadaljujemo naše delo s tabelami, si poglejmo še podatkovne tipe, ki jih lahko uporabljamo (kar nam bo pomagalo pri izdelavi bodočih tabel). Osnovni tipi, ki jih uporabljamo so:

Integer Text Date

Najprej bomo pregledali numerične vrednosti. Vsak numerični tip int je lahko tudi unsigned ali auto_increment. Če je unsigned, lahko zasede le pozitivne vrednosti, atribut auto_increment pa avtomatsko povečuje numerični tip (primer uporabe se bo videl v naslednjemu poglavju v tabeli študentov). Poleg vrednosti int lahko uporabljamo še sledeče tipe:

TINYINT – uporabljamo ga, kadar zasede argument majhne vrednosti (npr. število otrok). Lahko hrani števila med 0 in 255 če je unsigned ali od -128 do 127

SMALLINT – primeren z a števila od 0 do 65535 če je unsigned ali od -32768 do 32767

MEDIUMINT – zasede vrednosti od 0 do 16777215, obratno niti ne bomo gledali, ker ni tako pomembno

INT – od 0 do 4294967295 BIGINT – razpon je večji od int, se pa uporablja za ogromne vrednosti FLOAT – števila v plavajoči vejici, enojna natančnost

DOUBLE – števila v plavajoči vejici, dvojna natančnost DECIMAL – števila v plavajoči vejici predstavljana kot stringi

Sedaj pa si poglejmo še tipe za shranjevanja časa.

DATE – oblika: 2008-11-30 (Leto-Mesec-Dan) TIME – oblika: 12:35:10 (Ura-Minuta-Sekunda) DATETIME – oblika: 2008-11-30 12:35:10 (Leto-Mesec-Dan Ura-Minuta-

Sekunda) TIMESTAMP – oblika: 20081130123510 (brez ločnic zapisan datum in čas)

YEAR – oblika: 2008 (leto zapisano s štirimi številkami) Naslednji, ki pridejo na vrsto so tipi za shranjevanje stringov oziroma teksta.

Page 13: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

13

(a)SQL FRI

Edition

CHAR(x) – x je vrednost, koliko je maksimalno število znakov, ki jih lahko hranimo, lahko je od 0 - 255

VARCHAR(x) – x je lahko od 0 do 255, znaki pa morajo biti različni (npr. za vpis imen, priimkov)

TINYTEXT – uporabno za majhna besedila, ni občutljiv na velike in male znake TEXT – uporablja se za malce daljše tekste, tako kot tinytext tudi ta ni

občutljiv na velike in male znake MEDIUMTEXT – kot pove tip, tekst srednje velikosti, ni občutljiv na velike in

male znake

LONGTEXT – sprejme največ 2 na 32 – 1 znakov, če se malce matematično izrazimo

TINYBLOB – blob pomeni [B]inary [L]arge [OB]jects, uporablja se za tipe, kjer so iskanja občutljiva na velike in male črke

BLOB – sprejme večje vrednosti kot tinyblob MEDIUMBLOB – še večje vrednosti blob LONGBLOB – še večje kot mediumblob (velikosti so podobne kot pri tipu text)

ENUM – enum uporabljamo, kadar ţelimo da stolpec zaseţe le eno izmed določenih vrednosti (npr. spol) – primer uporabe bi bil: spol ENUM('M', 'Z')

SET – uporablja se za vstavljanje večih vrednosti npr. hobiji – primer uporabe bi bil: hobiji SET ('Lenarjenje', 'Pocivanje', 'Gledanje v zrak'), ko bi pa vstavljali v tabelo bi pa lahko vstavili ali vse ali pa ene izmed vrednosti: INSERT <tabela> (hobiji) values ('Lenarjenje', 'Pocivanje');

Za primer nekaterih tipov bomo naredili eno tabelo poroke, kjer bomo označili imena in priimke moţev, imena ţena (privzamemo za naš primer, da so vse sprejele moţeve priimke - optimizem je lahko včasih dobra stvar), če ţe imata mogoče kakšnega otroka, preden sta se poročila, datum poroke, uro poroke in število povabljenih. To bomo seveda naredili v naši bazi vaje.

mysql> CREATE TABLE poroke

-> (

-> ipmoza varchar(50),

-> izene varchar(20),

-> otrok enum('Da', 'Ne'),

-> dporoke DATE,

-> uporoke TIME,

-> pov tinyint unsigned

-> );

Query OK, 0 rows affected (0.50 sec)

Če malce pogledamo kaj smo naredili. Za ime in priimek moţa smo uporabili tip varchar in ga omejili na 50 znakov. Isto smo storili za ime ţene, le da smo ga omejili na 20. Za določitev, če ima par ţe otroka, smo uporabili tip enum, pri datumu poroke tip date, pri uri poroke tip time, za število povabljenih pa tip tinyint z unsigned (vrednosti od 0-255, recimo, da nobena ţena ni povabila več kot 255 gostov, kar bi bila ţe zelo draga in teţko obvladljiva poroka). Uporabimo še ukaz describe za prikaz naše tabele. Struktura tabele bi morala biti sledeča:

Page 14: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

14

(a)SQL FRI

Edition

mysql> DESCRIBE poroke;

+---------+---------------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+---------+---------------------+------+-----+---------+-------+

| ipmoza | varchar(50) | YES | | NULL | |

| izene | varchar(20) | YES | | NULL | |

| otrok | enum('Da','Ne') | YES | | NULL | |

| dporoke | date | YES | | NULL | |

| uporoke | time | YES | | NULL | |

| pov | tinyint(3) unsigned | YES | | NULL | |

+---------+---------------------+------+-----+---------+-------+

6 rows in set (0.30 sec)

Da pa nakaţemo, kaj bomo delali v naslednjemu poglavju, za preizkus vstavimo eno vrednost (s sintakso se bomo obremenjevali v naslednjemu poglavju).

mysql> INSERT INTO poroke

-> (ipmoza, izene, otrok, dporoke, uporoke, pov)

-> values

-> ('Bostjan Cigan', 'Anja', 'Ne', '2008-12-01', '14:00', 10);

Query OK, 1 row affected (0.16 sec)

Tabelo še izpišemo in morali bi dobiti sledečo situacijo:

mysql> SELECT * FROM poroke;

+---------------+-------+-------+------------+----------+------+

| ipmoza | izene | otrok | dporoke | uporoke | pov |

+---------------+-------+-------+------------+----------+------+

| Bostjan Cigan | Anja | Ne | 2008-12-01 | 14:00:00 | 10 |

+---------------+-------+-------+------------+----------+------+

1 row in set (0.00 sec)

Page 15: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

15

(a)SQL FRI

Edition

4. OSNOVNO DELO S TABELAMI All programmers are playwrights and all computers are lousy actors. – Neznan avtor V drugemu poglavju smo se naučili, kako izdelati bazo, in kako v tej bazi izdelati tabelo. V tem poglavju pa bomo malce obravnavali kako se splošno dela s tabelami. Ravno v drugem poglavju smo ustvarili tabelo studenti. Da ne bo tabela preveč prazna oziroma pusta, dajmo vstaviti vanjo nekaj podatkov. Za to se uporablja ukaz insert. INSERT INTO <ime tabele>

(<ime stolpca1>, <ime stolpca2>, ... <ime stolpca n>)

values

(<vrednost1>, <vrednost2>, ..., <vrednostn>);

Zopet, da ne bo preveč zmede, si poglejmo vse skupaj na splošnemu primeru. V tabelo bomo vstavili štiri študente. mysql> INSERT INTO studenti

-> (st_ime, st_priimek, letnik, smer)

-> values

-> ("Jaka", "Novak", 1, "VSS");

Query OK, 1 row affected (0.03 sec)

mysql> INSERT INTO studenti

-> (st_ime, st_priimek, letnik, smer)

-> values

-> ("Marko", "Stopar", 2, "ISRM");

Query OK, 1 row affected (0.03 sec)

mysql> INSERT INTO studenti

-> (st_ime, st_priimek, letnik, smer)

-> values

-> ("Zala", "Trcek", 3, "UNI");

Query OK, 1 row affected (0.02 sec)

mysql> -- Alternativna uporaba ukaza, brez navajanja stolpcev

mysql> INSERT INTO studenti

-> values

-> ("Tjasa", "Koper", 2, "VSS");

Query OK, 1 row affected (0.03 sec)

Kakor se opazi iz primera, se »Stringi« pišejo v navednicah, številske vrednosti pa brez navednic. Podatke, ki jih vstavljamo pa ločujemo z vejico. Kaj pa če ţelimo te podatke izpisati? Podatke izpišemo s pomočjo select stavka. SELECT <ime stolpca> FROM <ime tabele> (WHERE <pogoji>);

Page 16: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

16

(a)SQL FRI

Edition

V našem primeru ţelimo izpisati celotno tabelo in vse podatke. To bomo pa naredili takole: mysql> SELECT * FROM studenti;

+-------------+--------+------------+--------+------+

| id_studenta | st_ime | st_priimek | letnik | smer |

+-------------+--------+------------+--------+------+

| 1 | Jaka | Novak | 1 | VSS |

| 2 | Marko | Stopar | 2 | ISRM |

| 3 | Zala | Trcek | 3 | UNI |

| 4 | Tjasa | Koper | 2 | VSS |

+-------------+--------+------------+--------+------+

4 rows in set (0.00 sec)

Kot lahko vidimo, se * uporablja za izpis vseh stolpcev tabele. Za laţje delo s tabelo bomo vstavili še malce več študentov ampak na malce drugačen način. Insert stavke lahko vpišemo tudi v navadno .txt datoteko. Da pa podatke uvozimo, datoteko preprosto nekam shranimo (npr. na root direktorij na disku C) in vpišemo v CMD mysql –u root –p <ime baze> <<ime datoteke>

Konkretno v našem primeru: mysql –u root –p vaje <studenti.txt

Če sedaj poţenemo ukaz za prikaz tabele, naj bi dobili sledečo situacijo: mysql> SELECT * FROM studenti;

+-------------+---------+------------+--------+------+

| id_studenta | st_ime | st_priimek | letnik | smer |

+-------------+---------+------------+--------+------+

| 1 | Jaka | Novak | 1 | VSS |

| 2 | Marko | Stopar | 2 | ISRM |

| 3 | Zala | Trcek | 3 | UNI |

| 4 | Tjasa | Koper | 2 | VSS |

| 5 | Tjasa | Kopicnik | 1 | UNI |

| 6 | Domen | Prebel | 2 | VSS |

| 7 | Tjasa | Koper | 2 | VSS |

| 8 | Zlatko | Dren | 3 | ISRM |

| 9 | Zdravko | Dren | 2 | VSS |

| 10 | Tjasa | Cepel | 1 | VSS |

| 11 | Metka | Medved | 2 | ISRM |

| 12 | Tim | Andolsek | 4 | VSS |

| 13 | Tilen | Simoncic | 3 | VSS |

| 14 | Andreja | Suhodolcan | 2 | VSS |

| 15 | Aljaz | Petek | 4 | VSS |

| 16 | Miha | Jakse | 2 | UNI |

| 17 | Simon | Stepancic | 2 | VSS |

| 18 | Tine | Volcansek | 2 | VSS |

| 19 | Tjasa | Koper | 4 | ISRM |

| 20 | Alenka | Koper | 3 | VSS |

+-------------+---------+------------+--------+------+

20 rows in set (0.00 sec)

Page 17: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

17

(a)SQL FRI

Edition

Kaj pa če bi ţeleli izpisati samo imena, priimke in smer, ki jo študentje obiskujejo? To bi tudi lahko naredili z select stavkom, ki bi mu podali kaj naj izpiše. mysql> SELECT st_ime, st_priimek, smer FROM studenti;

+---------+------------+------+

| st_ime | st_priimek | smer |

+---------+------------+------+

| Jaka | Novak | VSS |

| Marko | Stopar | ISRM |

| Zala | Trcek | UNI |

| Tjasa | Koper | VSS |

| Tjasa | Kopicnik | UNI |

| Domen | Prebel | VSS |

| Tjasa | Koper | VSS |

| Zlatko | Dren | ISRM |

| Zdravko | Dren | VSS |

| Tjasa | Cepel | VSS |

| Metka | Medved | ISRM |

| Tim | Andolsek | VSS |

| Tilen | Simoncic | VSS |

| Andreja | Suhodolcan | VSS |

| Aljaz | Petek | VSS |

| Miha | Jakse | UNI |

| Simon | Stepancic | VSS |

| Tine | Volcansek | VSS |

| Tjasa | Koper | ISRM |

| Alenka | Koper | VSS |

+---------+------------+------+

20 rows in set (0.00 sec)

Pri zgornjemu izpisu smo omejili, katere stolpce nam bo izpisal MySQL. Kaj pa če bi ţeleli, da nam MySQL izpiše vse študente, ki obiskujejo določeno smer? mysql> SELECT st_ime, st_priimek, smer FROM studenti WHERE smer="VSS";

+---------+------------+------+

| st_ime | st_priimek | smer |

+---------+------------+------+

| Jaka | Novak | VSS |

| Tjasa | Koper | VSS |

| Domen | Prebel | VSS |

| Tjasa | Koper | VSS |

| Zdravko | Dren | VSS |

| Tjasa | Cepel | VSS |

| Tim | Andolsek | VSS |

| Tilen | Simoncic | VSS |

| Andreja | Suhodolcan | VSS |

| Aljaz | Petek | VSS |

| Simon | Stepancic | VSS |

| Tine | Volcansek | VSS |

| Alenka | Koper | VSS |

+---------+------------+------+

13 rows in set (0.03 sec)

Iz zgornjega primera ugotovimo, da s pomočjo where lahko izbiramo, katere podatke nam MySQL izpisuje. Naredimo še en primer, tokrat pa izpis omejimo tako, da izpišemo vse študente, ki niso vpisani v prvi letnik.

Page 18: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

18

(a)SQL FRI

Edition

mysql> SELECT st_ime, st_priimek, letnik FROM studenti WHERE letnik > 1;

+---------+------------+--------+

| st_ime | st_priimek | letnik |

+---------+------------+--------+

| Marko | Stopar | 2 |

| Zala | Trcek | 3 |

| Tjasa | Koper | 2 |

| Domen | Prebel | 2 |

| Tjasa | Koper | 2 |

| Zlatko | Dren | 3 |

| Zdravko | Dren | 2 |

| Metka | Medved | 2 |

| Tim | Andolsek | 4 |

| Tilen | Simoncic | 3 |

| Andreja | Suhodolcan | 2 |

| Aljaz | Petek | 4 |

| Miha | Jakse | 2 |

| Simon | Stepancic | 2 |

| Tine | Volcansek | 2 |

| Tjasa | Koper | 4 |

| Alenka | Koper | 3 |

+---------+------------+--------+

17 rows in set (0.00 sec)

Sedaj smo dobili izpis vseh študentov, ki so vpisani v višje letnike. Lahko bi napisali tudi sledeče in dobili enak odgovor: SELECT st_ime, st_priimek, letnik FROM studenti WHERE letnik != 1;

V where stavku torej lahko uporabljamo simbole <, >, =, !=. Kaj pa če bi ţeleli izpisati študente, ki so na isti smeri in v istem letniku? mysql> SELECT st_ime, st_priimek, smer, letnik

-> FROM studenti

-> WHERE smer="VSS" && letnik=1;

+--------+------------+------+--------+

| st_ime | st_priimek | smer | letnik |

+--------+------------+------+--------+

| Jaka | Novak | VSS | 1 |

| Tjasa | Cepel | VSS | 1 |

+--------+------------+------+--------+

2 rows in set (0.00 sec)

Da napišemo več pogojev uporabljamo ţe nam iz Jave znani operator &&. Kaj pa če bi morali izpisati študente, katerih imena se pričnejo na M? mysql> SELECT st_ime, st_priimek

-> FROM studenti

-> WHERE st_ime LIKE "M%";

+--------+------------+

| st_ime | st_priimek |

+--------+------------+

| Marko | Stopar |

| Metka | Medved |

| Miha | Jakse |

+--------+------------+

3 rows in set (0.00 sec)

Page 19: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

19

(a)SQL FRI

Edition

Operator like uporabljamo za iskanje nizov, pri katerih iščemo podobnosti. Če ţelimo na primer izpisati študente katerih priimki se končajo na ed, lahko to naredimo takole: mysql> SELECT st_ime, st_priimek

-> FROM studenti

-> WHERE st_priimek LIKE "%ed";

+--------+------------+

| st_ime | st_priimek |

+--------+------------+

| Metka | Medved |

+--------+------------+

1 row in set (0.00 sec)

Če bi pa ţeleli izpisati študente, katerih imena vsebujejo niz ark, je pa ukaz takšen: mysql> SELECT st_ime, st_priimek

-> FROM studenti

-> WHERE st_ime LIKE "%ark%";

+--------+------------+

| st_ime | st_priimek |

+--------+------------+

| Marko | Stopar |

+--------+------------+

1 row in set (0.00 sec)

Kaj pa če bi ţeleli izpisati študente ki so med prvim in četrtim letnikom? Tukaj pa pridejo v uporabo operatorji and, or in not. mysql> SELECT st_ime, st_priimek, letnik

-> FROM studenti

-> WHERE letnik > 1 AND letnik < 4;

+---------+------------+--------+

| st_ime | st_priimek | letnik |

+---------+------------+--------+

| Marko | Stopar | 2 |

| Zala | Trcek | 3 |

| Tjasa | Koper | 2 |

| Domen | Prebel | 2 |

| Tjasa | Koper | 2 |

| Zlatko | Dren | 3 |

| Zdravko | Dren | 2 |

| Metka | Medved | 2 |

| Tilen | Simoncic | 3 |

| Andreja | Suhodolcan | 2 |

| Miha | Jakse | 2 |

| Simon | Stepancic | 2 |

| Tine | Volcansek | 2 |

| Alenka | Koper | 3 |

+---------+------------+--------+

14 rows in set (0.00 sec)

Za primer operatorja or pa bomo izpisali vse študente, katerih imena se končajo na e ali a.

Page 20: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

20

(a)SQL FRI

Edition

mysql> SELECT st_ime, st_priimek, letnik, smer

-> FROM studenti

-> WHERE st_ime LIKE "%e" OR st_ime LIKE "%a";

+---------+------------+--------+------+

| st_ime | st_priimek | letnik | smer |

+---------+------------+--------+------+

| Jaka | Novak | 1 | VSS |

| Zala | Trcek | 3 | UNI |

| Tjasa | Koper | 2 | VSS |

| Tjasa | Kopicnik | 1 | UNI |

| Tjasa | Koper | 2 | VSS |

| Tjasa | Cepel | 1 | VSS |

| Metka | Medved | 2 | ISRM |

| Andreja | Suhodolcan | 2 | VSS |

| Miha | Jakse | 2 | UNI |

| Tine | Volcansek | 2 | VSS |

| Tjasa | Koper | 4 | ISRM |

| Alenka | Koper | 3 | VSS |

+---------+------------+--------+------+

12 rows in set (0.02 sec)

Za primer operatorja not, pa bomo izpisali študente, katerih priimki se ne končajo na k. mysql> SELECT st_ime, st_priimek, letnik, smer

-> FROM studenti

-> WHERE st_priimek NOT LIKE "%k";

+---------+------------+--------+------+

| st_ime | st_priimek | letnik | smer |

+---------+------------+--------+------+

| Marko | Stopar | 2 | ISRM |

| Tjasa | Koper | 2 | VSS |

| Domen | Prebel | 2 | VSS |

| Tjasa | Koper | 2 | VSS |

| Zlatko | Dren | 3 | ISRM |

| Zdravko | Dren | 2 | VSS |

| Tjasa | Cepel | 1 | VSS |

| Metka | Medved | 2 | ISRM |

| Tilen | Simoncic | 3 | VSS |

| Andreja | Suhodolcan | 2 | VSS |

| Miha | Jakse | 2 | UNI |

| Simon | Stepancic | 2 | VSS |

| Tjasa | Koper | 4 | ISRM |

| Alenka | Koper | 3 | VSS |

+---------+------------+--------+------+

14 rows in set (0.00 sec)

Kadar ţelimo delati selekcijo nad določenim atributom, obstajajo tudi operatorji, ki nam malce olajšajo delo. Tak operator je operator in, s pomočjo katerega lahko zdruţimo več pogojev. Izpisali bomo vse študente, ki so na smeri ISRM in VSS.

Page 21: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

21

(a)SQL FRI

Edition

mysql> SELECT st_ime, st_priimek, smer

-> FROM studenti

-> WHERE smer IN ('ISRM', 'VSS');

+---------+------------+------+

| st_ime | st_priimek | smer |

+---------+------------+------+

| Jaka | Novak | VSS |

| Marko | Stopar | ISRM |

| Tjasa | Koper | VSS |

| Domen | Prebel | VSS |

| Tjasa | Koper | VSS |

| Zlatko | Dren | ISRM |

| Zdravko | Dren | VSS |

| Tjasa | Cepel | VSS |

| Metka | Medved | ISRM |

| Tim | Andolsek | VSS |

| Tilen | Simoncic | VSS |

| Andreja | Suhodolcan | VSS |

| Aljaz | Petek | VSS |

| Simon | Stepancic | VSS |

| Tine | Volcansek | VSS |

| Tjasa | Koper | ISRM |

| Alenka | Koper | VSS |

+---------+------------+------+

17 rows in set (0.03 sec)

Če in zanikamo, bomo dobili vse študente, ki niso na smeri VSS in ISRM. mysql> SELECT st_ime, st_priimek, smer

-> FROM studenti

-> WHERE smer NOT IN ('ISRM', 'VSS');

+--------+------------+------+

| st_ime | st_priimek | smer |

+--------+------------+------+

| Zala | Trcek | UNI |

| Tjasa | Kopicnik | UNI |

| Miha | Jakse | UNI |

+--------+------------+------+

3 rows in set (0.00 sec)

V eni izmed prejšnjih nalog smo izpisali vse študente, ki so vpisani v višji letnik. Za to operacijo lahko uporabimo operator between.

Page 22: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

22

(a)SQL FRI

Edition

mysql> SELECT st_ime, st_priimek, letnik

-> FROM studenti

-> WHERE letnik BETWEEN 2 AND 4;

+---------+------------+--------+

| st_ime | st_priimek | letnik |

+---------+------------+--------+

| Marko | Stopar | 2 |

| Zala | Trcek | 3 |

| Tjasa | Koper | 2 |

| Domen | Prebel | 2 |

| Tjasa | Koper | 2 |

| Zlatko | Dren | 3 |

| Zdravko | Dren | 2 |

| Metka | Medved | 2 |

| Tim | Andolsek | 4 |

| Tilen | Simoncic | 3 |

| Andreja | Suhodolcan | 2 |

| Aljaz | Petek | 4 |

| Miha | Jakse | 2 |

| Simon | Stepancic | 2 |

| Tine | Volcansek | 2 |

| Tjasa | Koper | 4 |

| Alenka | Koper | 3 |

+---------+------------+--------+

17 rows in set (0.01 sec)

Če vse skupaj zanikamo in napišemo not between, bomo dobili vse študente prvega letnika. mysql> SELECT st_ime, st_priimek, letnik

-> FROM studenti

-> WHERE letnik NOT BETWEEN 2 AND 4;

+--------+------------+--------+

| st_ime | st_priimek | letnik |

+--------+------------+--------+

| Jaka | Novak | 1 |

| Tjasa | Kopicnik | 1 |

| Tjasa | Cepel | 1 |

+--------+------------+--------+

3 rows in set (0.00 sec)

Pri vseh ukazih nam je do sedaj MySQL izpisoval podatke tako, kakor so bili vpisani v bazo po vrsti. Če pa bi ţeleli, da se nam podatki izpisujejo po vrsti po določenemu atributu, lahko pa uporabimo ukaz order by. mysql> SELECT st_ime, smer, letnik

-> FROM studenti

-> WHERE letnik = 1 OR letnik = 4 ORDER BY st_ime;

+--------+------+--------+

| st_ime | smer | letnik |

+--------+------+--------+

| Aljaz | VSS | 4 |

| Jaka | VSS | 1 |

| Tim | VSS | 4 |

| Tjasa | UNI | 1 |

| Tjasa | VSS | 1 |

| Tjasa | ISRM | 4 |

+--------+------+--------+

6 rows in set (0.00 sec)

Page 23: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

23

(a)SQL FRI

Edition

Izpis lahko urejamo tudi naraščajoče ali padajoče s pomočjo ukazov asc in desc.

mysql> -- Izpis naraščajoče s pomočjo ASC

mysql> SELECT st_ime

-> FROM studenti

-> ORDER BY st_ime ASC;

+---------+

| st_ime |

+---------+

| Alenka |

| Aljaz |

| Andreja |

| Domen |

| Jaka |

| Marko |

| Metka |

| Miha |

| Simon |

| Tilen |

| Tim |

| Tine |

| Tjasa |

| Tjasa |

| Tjasa |

| Tjasa |

| Tjasa |

| Zala |

| Zdravko |

| Zlatko |

+---------+

20 rows in set (0.00 sec)

Pri izpisu si včasih ne ţelimo izpisati mogoče vseh vrednosti, ampak ţelimo izpis nekako omejiti. Kaj takega pa lahko naredimo z ukazom limit. Pa dajmo izpisati naše študente, a tokrat samo prvih pet. mysql> SELECT st_ime, st_priimek

-> FROM studenti

-> LIMIT 5;

+--------+------------+

| st_ime | st_priimek |

+--------+------------+

| Jaka | Novak |

| Marko | Stopar |

| Zala | Trcek |

| Tjasa | Koper |

| Tjasa | Kopicnik |

+--------+------------+

5 rows in set (0.00 sec)

Page 24: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

24

(a)SQL FRI

Edition

Limit lahko pa uporabljamo tudi v navezi z order by. V našemu primeru bi tako izpisali prve tri študente iz prvega letnika. mysql> SELECT st_ime, st_priimek, smer, letnik

-> FROM studenti

-> ORDER BY letnik

-> LIMIT 3;

+--------+------------+------+--------+

| st_ime | st_priimek | smer | letnik |

+--------+------------+------+--------+

| Jaka | Novak | VSS | 1 |

| Tjasa | Kopicnik | UNI | 1 |

| Tjasa | Cepel | VSS | 1 |

+--------+------------+------+--------+

3 rows in set (0.00 sec)

Ukazu limit pa lahko podamo tudi dva argumenta, in sicer v kateri vrstici naj začne in koliko vrstic naprej naj izpiše (v našem primeru bo to od šeste vrstice naprej, prva dva študenta).

mysql> SELECT st_ime, st_priimek, smer, letnik

-> FROM studenti

-> LIMIT 6,2;

+---------+------------+------+--------+

| st_ime | st_priimek | smer | letnik |

+---------+------------+------+--------+

| Tjasa | Koper | VSS | 2 |

| Zlatko | Dren | ISRM | 3 |

+---------+------------+------+--------+

2 rows in set (0.00 sec)

Recimo da bi ţeleli izpisati, koliko letnikov ima naša fakulteta. Uporabimo ukaz select. mysql> SELECT letnik FROM studenti;

+--------+

| letnik |

+--------+

| 1 |

| 2 |

| 3 |

| 2 |

| 1 |

| 2 |

| 2 |

| 3 |

| 2 |

| 1 |

| 2 |

| 4 |

| 3 |

| 2 |

| 4 |

| 2 |

| 2 |

| 2 |

| 4 |

| 3 |

+--------+

20 rows in set (0.00 sec)

Page 25: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

25

(a)SQL FRI

Edition

Kakor vidimo, se zapisi podvajajo (oziroma v našem primeru, več kot podvajajo). Zato zraven select ukaza uporabimo ukaz distinct, ki iz izpisa odstrani duplikate. mysql> SELECT DISTINCT letnik FROM studenti;

+--------+

| letnik |

+--------+

| 1 |

| 2 |

| 3 |

| 4 |

+--------+

4 rows in set (0.13 sec)

Preden končamo z izpisovanjem podatkov na različne načine, si pa poglejmo še imenovanje stolpcev. Pri izpisu ţelimo, da bi se nam namesto imena stolpcev st_ime, st_priimek izpisalo Ime, Priimek. Za ta namen uporabljamo ukaz as.

mysql> SELECT st_ime AS 'Ime', st_priimek AS 'Priimek', letnik AS 'Letnik'

-> FROM studenti

-> WHERE letnik = 1;

+-------+----------+--------+

| Ime | Priimek | Letnik |

+-------+----------+--------+

| Jaka | Novak | 1 |

| Tjasa | Kopicnik | 1 |

| Tjasa | Cepel | 1 |

+-------+----------+--------+

3 rows in set (0.00 sec)

Do sedaj smo se naučili podatke vstavljati in izpisovati na različne načine. Sedaj pa poskusimo podatke še brisati in urejati. Na primer da ţelimo spremeniti ime smeri UNI v UNIB (bolonjski univerzitetni). Vse to lahko storimo z ukazom update. mysql> UPDATE studenti

-> SET smer = 'UNIB'

-> WHERE smer = 'UNI';

Query OK, 3 rows affected (0.09 sec)

Rows matched: 3 Changed: 3 Warnings: 0

Z set ukazom smo nastavili novo vrednost z where pa določili katere vrednosti naj se zamenjajo. Če izpišemo našo tabelo sedaj (po parametru UNI, ki je bil prej) in po parametru UNIB (ki je sedaj) dobimo sledeče: mysql> SELECT st_ime, st_priimek, smer, letnik

-> FROM studenti

-> WHERE smer = 'UNI';

Empty set (0.00 sec)

Empty set nam pove, da MySQL ni našel zapisov, ki ustrezajo našemu iskalnemu kriteriju.

Page 26: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

26

(a)SQL FRI

Edition

mysql> SELECT st_ime, st_priimek, smer, letnik

-> FROM studenti

-> WHERE smer = 'UNIB';

+--------+------------+------+--------+

| st_ime | st_priimek | smer | letnik |

+--------+------------+------+--------+

| Zala | Trcek | UNIB | 3 |

| Tjasa | Kopicnik | UNIB | 1 |

| Miha | Jakse | UNIB | 2 |

+--------+------------+------+--------+

3 rows in set (0.00 sec)

Če pa ţelimo podatke brisati, pa to počnemo z ukazom delete. Dajmo pobrisati vse študente smeri UNIB in VSS in potem izpisati tabelo. Splošna uporaba delete ukaza:

DELETE FROM <ime tabele> WHERE (pogoj);

Če ne navedemo pogoja, ukaz delete pobriše celotno tabelo. mysql> DELETE

-> FROM studenti

-> WHERE smer = 'UNIB';

Query OK, 3 rows affected (0.05 sec)

mysql> DELETE

-> FROM studenti

-> WHERE smer = 'VSS';

Query OK, 13 rows affected (0.05 sec)

mysql> SELECT st_ime, st_priimek, smer, letnik FROM studenti;

+--------+------------+------+--------+

| st_ime | st_priimek | smer | letnik |

+--------+------------+------+--------+

| Marko | Stopar | ISRM | 2 |

| Zlatko | Dren | ISRM | 3 |

| Metka | Medved | ISRM | 2 |

| Tjasa | Koper | ISRM | 4 |

+--------+------------+------+--------+

4 rows in set (0.00 sec)

Sedaj ko so nam ostali samo še štirje študenti (skorajda enako številu študentov v četrtem letniku na smeri IŠRM), bi jih lahko razporedili po imenih in priimkih. Za ta namen bomo imena in priimke zdruţili. mysql> SELECT CONCAT (st_ime, ' ', st_priimek) AS Ime

-> FROM studenti

-> ORDER BY ime;

+--------------+

| Ime |

+--------------+

| Marko Stopar |

| Metka Medved |

| Tjasa Koper |

| Zlatko Dren |

+--------------+

4 rows in set (0.08 sec)

Page 27: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

27

(a)SQL FRI

Edition

S pomočjo select concat lahko zdruţimo dva stolpca v enega. Zgoraj smo kot ločnico med imenom in priimkom uporabili presledek. Spoznali smo osnovne operacije za delo nad tabelami. Ostane nam še igranje z datumi. Za ta namen bomo ustvarili novo tabelo, ki bo vsebovala otroke, ki so se rodili v preteklih desetih letih (no, ne ravno vse, čeravno naj bi rodnost v Sloveniji upadala, mogoče bi pa pomagal kakšen električni mrk za en teden). mysql> CREATE TABLE otroki

-> (

-> id_otroka int unsigned not null auto_increment primary key,

-> o_ime varchar(20),

-> o_priimek varchar(20),

-> rojstvo DATE

-> );

Query OK, 0 rows affected (0.13 sec)

Za parameter rojstvo smo uporabili date, ki ga MySQL avtomatsko razume kot vrednost datum. Da pa tabela ne bo prazna, uvozite datoteko otroki.txt. mysql –u root –p vaje <otroki.txt

Naša tabela bi po izpisu morala izgledali takole: mysql> SELECT * FROM otroki;

+-----------+--------+-----------+------------+

| id_otroka | o_ime | o_priimek | rojstvo |

+-----------+--------+-----------+------------+

| 1 | Jaka | Novak | 1990-12-05 |

| 2 | Miha | Trubar | 1991-01-04 |

| 3 | Janez | Jakopic | 1993-11-01 |

| 4 | Jaka | Kobilica | 1997-12-11 |

| 5 | Jana | Mladovan | 1999-10-06 |

| 6 | Nejc | Pintar | 2001-12-07 |

| 7 | Tjasa | Pintar | 2003-11-02 |

| 8 | Demi | Okorn | 2000-05-02 |

| 9 | Primoz | Kern | 2007-02-03 |

| 10 | Luka | Koper | 2001-01-02 |

| 11 | Mirna | Korencek | 2008-11-05 |

+-----------+--------+-----------+------------+

11 rows in set (0.00 sec)

Dajmo izpisati vse otroke, ki so se rodili med letom 1995 in letom 2008. Za izpis bomo uporabili ukaz between in primerjavo dveh stringov.

Page 28: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

28

(a)SQL FRI

Edition

mysql> SELECT o_ime, o_priimek, rojstvo

-> FROM otroki

-> WHERE rojstvo BETWEEN '1995-01-01' AND '2008-01-01';

+--------+-----------+------------+

| o_ime | o_priimek | rojstvo |

+--------+-----------+------------+

| Jaka | Kobilica | 1997-12-11 |

| Jana | Mladovan | 1999-10-06 |

| Nejc | Pintar | 2001-12-07 |

| Tjasa | Pintar | 2003-11-02 |

| Demi | Okorn | 2000-05-02 |

| Primoz | Kern | 2007-02-03 |

| Luka | Koper | 2001-01-02 |

+--------+-----------+------------+

7 rows in set (0.09 sec)

Seveda pa se da to storiti tudi drugače. Ker imamo stolpec, za katerega MySQL ve, da je datum, lahko uporabimo vgrajene operatorje. Izpišimo otroke, ki so se rodili na intervalu od leta 1995 in 2008.

mysql> SELECT o_ime, o_priimek, rojstvo

-> FROM otroki

-> WHERE YEAR(rojstvo) BETWEEN '1995' AND '2008';

+--------+-----------+------------+

| o_ime | o_priimek | rojstvo |

+--------+-----------+------------+

| Jaka | Kobilica | 1997-12-11 |

| Jana | Mladovan | 1999-10-06 |

| Nejc | Pintar | 2001-12-07 |

| Tjasa | Pintar | 2003-11-02 |

| Demi | Okorn | 2000-05-02 |

| Primoz | Kern | 2007-02-03 |

| Luka | Koper | 2001-01-02 |

| Mirna | Korencek | 2008-11-05 |

+--------+-----------+------------+

8 rows in set (0.05 sec)

Kaj pa če bi ţeleli izpisati vse otroke, ki so se rodili Januarja? Tudi to bi lahko storili z uporabo ukaza month, lahko pa uporabimo tudi monthname in angleško ime meseca.

mysql> SELECT o_ime, o_priimek, rojstvo

-> FROM otroki

-> WHERE MONTH(rojstvo) = '01';

+-------+-----------+------------+

| o_ime | o_priimek | rojstvo |

+-------+-----------+------------+

| Miha | Trubar | 1991-01-04 |

| Luka | Koper | 2001-01-02 |

+-------+-----------+------------+

2 rows in set (0.03 sec)

Page 29: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

29

(a)SQL FRI

Edition

mysql> -- Alternativna uporaba z monthname

mysql> SELECT o_ime, o_priimek, rojstvo

-> FROM otroki

-> WHERE MONTHNAME(rojstvo) = 'January';

+-------+-----------+------------+

| o_ime | o_priimek | rojstvo |

+-------+-----------+------------+

| Miha | Trubar | 1991-01-04 |

| Luka | Koper | 2001-01-02 |

+-------+-----------+------------+

2 rows in set (0.05 sec)

Kaj pa če bi ţeleli izpisati vse otroke, kateri so bili rojeni na isti mesec v kateremu pišemo trenuten ukaz? Uporabimo lahko current_date (v času pisanja je to november).

mysql> SELECT o_ime, o_priimek, rojstvo

-> FROM otroki

-> WHERE MONTH(rojstvo) = MONTH(CURRENT_DATE);

+-------+-----------+------------+

| o_ime | o_priimek | rojstvo |

+-------+-----------+------------+

| Janez | Jakopic | 1993-11-01 |

| Tjasa | Pintar | 2003-11-02 |

| Mirna | Korencek | 2008-11-05 |

+-------+-----------+------------+

3 rows in set (0.03 sec)

Urejanje po rojstvih poteka na enak način kot urejanje podatkov.

mysql> SELECT o_ime, o_priimek, rojstvo

-> FROM otroki

-> ORDER BY rojstvo;

+--------+-----------+------------+

| o_ime | o_priimek | rojstvo |

+--------+-----------+------------+

| Jaka | Novak | 1990-12-05 |

| Miha | Trubar | 1991-01-04 |

| Janez | Jakopic | 1993-11-01 |

| Jaka | Kobilica | 1997-12-11 |

| Jana | Mladovan | 1999-10-06 |

| Demi | Okorn | 2000-05-02 |

| Luka | Koper | 2001-01-02 |

| Nejc | Pintar | 2001-12-07 |

| Tjasa | Pintar | 2003-11-02 |

| Primoz | Kern | 2007-02-03 |

| Mirna | Korencek | 2008-11-05 |

+--------+-----------+------------+

11 rows in set (0.02 sec)

Page 30: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

30

(a)SQL FRI

Edition

5. ARITMETIKA It's not a bug – it's an undocumented feature. – Neznan avtor V MySQLu lahko nad tabelami izvajamo tudi aritmetične operacije. Kot zgled dajmo v naši bazi vaje ustvariti tabelo delavci. V njej imamo shranjena imena in priimke, mesečni zasluţek, ter bonus, ki se ga dobi na število obdelanih strank. mysql> CREATE TABLE delavci

-> (

-> id_delavca int unsigned not null auto_increment primary key,

-> d_ime varchar(20),

-> d_priimek varchar(20),

-> placa int,

-> dodatek int

-> );

Query OK, 0 rows affected (0.44 sec)

Uvozite v bazo datoteko delavci.txt, da naša tabela ne bo tako porazno prazna. mysql –u root –p vaje <delavci.txt

Po select ukazu, bi morali imeti sledeče stanje: mysql> SELECT * FROM delavci;

+------------+---------+------------+-------+---------+

| id_delavca | d_ime | d_priimek | placa | dodatek |

+------------+---------+------------+-------+---------+

| 1 | Tjasa | Kopicnik | 1250 | 40 |

| 2 | Domen | Prebel | 1417 | 0 |

| 3 | Tjasa | Kopicnik | 1250 | 40 |

| 4 | Domen | Prebel | 1417 | 0 |

| 5 | Tjasa | Koper | 1267 | 5 |

| 6 | Zlatko | Dren | 1100 | 10 |

| 7 | Zdravko | Dren | 1000 | 20 |

| 8 | Tjasa | Cepel | 2200 | 10 |

| 9 | Metka | Medved | 2100 | 10 |

| 10 | Tim | Andolsek | 1000 | 50 |

| 11 | Tilen | Simoncic | 4000 | 20 |

| 12 | Andreja | Suhodolcan | 1000 | 50 |

| 13 | Aljaz | Petek | 4000 | 200 |

| 14 | Miha | Jakse | 800 | 50 |

| 15 | Simon | Stepancic | 1241 | 42 |

| 16 | Tine | Volcansek | 1426 | 47 |

| 17 | Tjasa | Koper | 1234 | 24 |

| 18 | Alenka | Koper | 1002 | 512 |

+------------+---------+------------+-------+---------+

18 rows in set (0.05 sec)

Poskušajmo sedaj najti minimalno plačo in minimalni dodatek. SQL ima vgrajen ukaz min za take namene.

Page 31: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

31

(a)SQL FRI

Edition

mysql> SELECT MIN(placa) FROM delavci;

+------------+

| MIN(placa) |

+------------+

| 800 |

+------------+

1 row in set (0.03 sec)

mysql> SELECT MIN(dodatek) FROM delavci;

+--------------+

| MIN(dodatek) |

+--------------+

| 0 |

+--------------+

1 row in set (0.00 sec)

Če bi ţeleli poiskati največjo plačo in največji dodatek, bi bil ukaz podoben. mysql> SELECT MAX(placa) FROM delavci;

+------------+

| MAX(placa) |

+------------+

| 4000 |

+------------+

1 row in set (0.00 sec)

mysql> SELECT MAX(dodatek) FROM delavci;

+--------------+

| MAX(dodatek) |

+--------------+

| 512 |

+--------------+

1 row in set (0.00 sec)

Dajmo še pogledati, koliko je naše podjetje ta mesec izplačalo delavcem. MySQL ima vgrajen ukaz sum, za vsoto podatkov v stolpcu.

mysql> SELECT SUM(placa) FROM delavci;

+------------+

| SUM(placa) |

+------------+

| 28704 |

+------------+

1 row in set (0.05 sec)

mysql> SELECT SUM(dodatek) FROM delavci;

+--------------+

| SUM(dodatek) |

+--------------+

| 1130 |

+--------------+

1 row in set (0.06 sec)

Seveda nam to ni všeč, saj vse skupaj ne bomo seštevali na roke. Pa dajmo ta ukaz napisati malce drugače.

Page 32: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

32

(a)SQL FRI

Edition

mysql> SELECT SUM(placa) + SUM(dodatek) FROM delavci;

+---------------------------+

| SUM(placa) + SUM(dodatek) |

+---------------------------+

| 29834 |

+---------------------------+

1 row in set (0.00 sec)

Iz statističnega urada Republike Slovenije so našemu podjetju sporočili, da ţelijo vedeti koliko je povprečna plača (brez dodatkov) naših delavcev. Logika nam govori, da za to potrebujemo le vedeti število zaposlenih in vsoto vseh plač, ter vse skupaj deliti.

mysql> SELECT COUNT(*) FROM delavci;

+----------+

| COUNT(*) |

+----------+

| 18 |

+----------+

1 row in set (0.03 sec)

Za število vrstic (oziroma število delavcev) smo uporabili ukaz count. Sedaj pa uporabimo še ukaz sum in vse skupaj delimo.

mysql> SELECT SUM(placa)/COUNT(*) FROM delavci;

+---------------------+

| SUM(placa)/COUNT(*) |

+---------------------+

| 1594.6667 |

+---------------------+

1 row in set (0.00 sec)

Vse skupaj bi lahko laţje izvedeli s pomočjo funkcije avg.

mysql> SELECT AVG(placa) FROM delavci;

+------------+

| AVG(placa) |

+------------+

| 1594.6667 |

+------------+

1 row in set (0.00 sec)

Kot vidimo, nam MySQL avtomatično zračuna povprečno plačo. Poleg operacij seštevanja, odštevanja, mnoţenja, deljenja, MySQL pozna tudi % (ostanek pri deljenju), absolutno vrednost, zaokroţevanje, izračun trigonometričnih funkcij itd. Poglejmo si vse skupaj na primerih. mysql> SELECT 21%6;

+------+

| 21%6 |

+------+

| 3 |

+------+

1 row in set (0.00 sec)

Page 33: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

33

(a)SQL FRI

Edition

mysql> -- Isti ukaz, malce drugače napisano

mysql> SELECT MOD(21,6);

+-----------+

| MOD(21,6) |

+-----------+

| 3 |

+-----------+

1 row in set (0.00 sec) mysql> -- Absolutna vrednost števila -4.552

mysql> SELECT ABS(-4.552);

+-------------+

| ABS(-4.552) |

+-------------+

| 4.552 |

+-------------+

1 row in set (0.05 sec)

mysql> -- Potenciranje, 4 na 0.5 (koren iz 4)

mysql> SELECT POWER(4, 0.5);

+---------------+

| POWER(4, 0.5) |

+---------------+

| 2 |

+---------------+

1 row in set (0.05 sec)

mysql> -- Potenciranje, 2 na 6to

mysql> SELECT POWER(2, 6);

+-------------+

| POWER(2, 6) |

+-------------+

| 64 |

+-------------+

1 row in set (0.00 sec)

mysql> -- Kvadratni koren števila 55

mysql> SELECT SQRT(55);

+-----------------+

| SQRT(55) |

+-----------------+

| 7.4161984870957 |

+-----------------+

1 row in set (0.00 sec)

mysql> -- Zaokroževanje na celo število

mysql> SELECT ROUND(7.555);

+--------------+

| ROUND(7.555) |

+--------------+

| 8 |

+--------------+

1 row in set (0.02 sec)

Page 34: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

34

(a)SQL FRI

Edition

mysql> -- Zaokrožitev na določeno število decimalk

mysql> SELECT ROUND(7.5554321, 2);

+---------------------+

| ROUND(7.5554321, 2) |

+---------------------+

| 7.56 |

+---------------------+

1 row in set (0.00 sec)

mysql> -- Izračun sinusa

mysql> SELECT SIN(0);

+--------+

| SIN(0) |

+--------+

| 0 |

+--------+

1 row in set (0.00 sec)

mysql> -- Izračun kosinusa

mysql> SELECT COS(0);

+--------+

| COS(0) |

+--------+

| 1 |

+--------+

1 row in set (0.00 sec)

mysql> -- Izračun tangensa

mysql> SELECT TAN(0);

+--------+

| TAN(0) |

+--------+

| 0 |

+--------+

1 row in set (0.00 sec)

Page 35: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

35

(a)SQL FRI

Edition

6. DELO NAD MNOŽICAMI TABEL V četrtem in petem poglavju smo spoznali osnovne operacije nad tabelami in izvajanje aritmetičnih operacij. V realnem svetu vsi podatki nikoli niso hranjeni v eni tabeli, ampak v večih. Za naše testne namene bomo ustvarili tri nove tabele. V eni tabeli bodo študentje (ime, priimek, datum rojstva, letnik, smer), v drugi tabeli bodo hranjena leta prvega vpisa na faks, redno, izredno in tip vpisa (V1, PR – Vpis prvič in prepis), v tretji pa izpit, ki ga je študent nazadnje pisal, datum pisanja in število polaganj izpita. Uvoden korak bo pa seveda izbris obstoječe tabele študenti. mysql> DROP TABLE studenti;

Query OK, 0 rows affected (0.38 sec)

Poglejmo si najprej strukturo naših tabel, ki jih bomo naredili:

studenti

idst

ime

priimek

d_roj

let

smer

Naše izpise bomo povezovali s pomočjo ključev (primary key). V tabeli studenti je to idst, v izpit idiz, v vpisi pa idvp. Ključe bomo avtomatsko povečevali vsakič, ko se bo pojavil nov vpis (lahko pa bi jih vpisovali tudi sami). Pa dajmo tabele najprej ustvariti. mysql> CREATE TABLE studenti

-> (

-> idst int not null auto_increment primary key,

-> ime varchar(20),

-> priimek varchar(20),

-> d_roj DATE not null,

-> let int not null,

-> smer varchar(5)

-> );

Query OK, 0 rows affected (1.23 sec)

mysql> CREATE TABLE izpiti

-> (

-> idiz int NOT NULL auto_increment primary key,

-> izpit varchar(50),

-> dat DATE,

-> stp int

-> );

Query OK, 0 rows affected (0.23 sec)

mysql> CREATE TABLE vpisi

-> (

-> idvp int not null auto_increment primary key,

-> letov YEAR,

-> ri enum('RD', 'IZR'),

-> tv enum('V1', 'PR')

-> );

Query OK, 0 rows affected (0.19 sec)

vpisi

idvp

letov

ri

tv

izpiti

idiz

izpit

dat

stp

Page 36: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

36

(a)SQL FRI

Edition

mysql> DESCRIBE studenti;

+---------+-------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+---------+-------------+------+-----+---------+----------------+

| idst | int(11) | NO | PRI | NULL | auto_increment |

| ime | varchar(20) | YES | | NULL | |

| priimek | varchar(20) | YES | | NULL | |

| d_roj | date | NO | | NULL | |

| let | int(11) | NO | | NULL | |

| smer | varchar(5) | YES | | NULL | |

+---------+-------------+------+-----+---------+----------------+

6 rows in set (0.52 sec)

mysql> DESCRIBE izpiti;

+-------+-------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+-------------+------+-----+---------+----------------+

| idiz | int(11) | NO | PRI | NULL | auto_increment |

| izpit | varchar(50) | YES | | NULL | |

| dat | date | YES | | NULL | |

| stp | int(11) | YES | | NULL | |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.05 sec)

mysql> DESCRIBE vpisi;

+-------+------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+------------------+------+-----+---------+----------------+

| idvp | int(11) | NO | PRI | NULL | auto_increment |

| letov | year(4) | YES | | NULL | |

| ri | enum('RD','IZR') | YES | | NULL | |

| tv | enum('V1','PR') | YES | | NULL | |

+-------+------------------+------+-----+---------+----------------+

4 rows in set (0.20 sec)

Da pa zopet naše tabele ne bodo puste bomo iz datotek studentip6.txt, izpiti.txt in vpisi.txt izvedli vpise (točnost podatkov niti ni pomembna, saj se nekje pojavljajo študentje v četrtem letniku, ki opravljajo izpit OPB). Izvedimo sledeče ukaze: mysql -u root -p vaje <studentip6.txt

mysql -u root -p vaje <izpiti.txt

mysql -u root -p vaje <vpisi.txt

Naše tabele sedaj izgledajo takole:

mysql> SELECT * FROM studenti;

+------+---------+----------+------------+-----+------+

| idst | ime | priimek | d_roj | let | smer |

+------+---------+----------+------------+-----+------+

| 1 | Tjasa | Kopicnik | 1987-12-01 | 1 | VSS |

| 2 | Domen | Prebel | 1987-11-02 | 2 | ISRM |

| 3 | Tjasa | Koper | 1986-10-03 | 3 | VSS |

| 4 | Zlatko | Dren | 1988-12-02 | 1 | UNI |

| 5 | Zdravko | Dren | 1989-03-15 | 2 | ISRM |

| 6 | Tjasa | Cepel | 1986-01-01 | 2 | UNI |

| 7 | Metka | Medved | 1985-04-01 | 3 | VSS |

| 8 | Tim | Andolsek | 1986-08-09 | 4 | VSS |

+------+---------+----------+------------+-----+------+

8 rows in set (0.00 sec)

Page 37: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

37

(a)SQL FRI

Edition

mysql> SELECT * FROM izpiti;

+------+-------+------------+------+

| idiz | izpit | dat | stp |

+------+-------+------------+------+

| 1 | DS | 2008-02-01 | 2 |

| 2 | ANA1 | 2007-03-01 | 1 |

| 3 | ANA1 | 2007-02-05 | 1 |

| 4 | OP1 | 2006-02-03 | 2 |

| 5 | OP2 | 2007-02-06 | 4 |

| 6 | OP1 | 2007-03-05 | 5 |

| 7 | OPB | 2006-01-02 | 6 |

| 8 | PB | 2008-02-01 | 0 |

+------+-------+------------+------+

8 rows in set (0.00 sec)

mysql> SELECT * FROM vpisi;

+------+-------+------+------+

| idvp | letov | ri | tv |

+------+-------+------+------+

| 1 | 2008 | RD | V1 |

| 2 | 2006 | RD | V1 |

| 3 | 2005 | IZR | V1 |

| 4 | 2007 | IZR | V1 |

| 5 | 2008 | RD | PR |

| 6 | 2004 | RD | PR |

| 7 | 2005 | RD | PR |

| 8 | 2008 | IZR | V1 |

+------+-------+------+------+

8 rows in set (0.00 sec)

Dajmo izpisati vse študente, ki so polagali kakršenkoli izpit več kot enkrat. Če bi to delali po osnovni logiki iz četrtega poglavja, bi to naredili takole:

mysql> SELECT ime, priimek, stp

-> FROM studenti, izpiti

-> WHERE stp > 1;

S tako sintakso nam MySQL vrne 40 zapisov. Zakaj? Ker imamo osem študentov v tabeli studenti, v tabeli izpiti pa imamo pet vrstic, kjer je stp več kot ena. Dobili smo v bistvu število kombinacij. Pravilen način kako bi to naredili je sledeč: mysql> SELECT ime, priimek, stp

-> FROM studenti, izpiti

-> WHERE studenti.idst = izpiti.idiz AND stp > 1;

+---------+----------+------+

| ime | priimek | stp |

+---------+----------+------+

| Tjasa | Kopicnik | 2 |

| Zlatko | Dren | 2 |

| Zdravko | Dren | 4 |

| Tjasa | Cepel | 5 |

| Metka | Medved | 6 |

+---------+----------+------+

5 rows in set (0.00 sec)

Če razloţimo malce where vrstico. Pogledali smo id številke študentov in id-je izpitov ter smo jih enačili. S pomočjo tega smo dobili le pravilne kombinacije. Ker pa je pisanje dolgotrajno, si ga pa lahko olajšamo takole:

Page 38: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

38

(a)SQL FRI

Edition

mysql> SELECT ime, priimek, stp

-> FROM studenti s, izpiti i

-> WHERE s.idst = i.idiz AND stp > 1;

+---------+----------+------+

| ime | priimek | stp |

+---------+----------+------+

| Tjasa | Kopicnik | 2 |

| Zlatko | Dren | 2 |

| Zdravko | Dren | 4 |

| Tjasa | Cepel | 5 |

| Metka | Medved | 6 |

+---------+----------+------+

5 rows in set (0.00 sec)

Uporabili smo aliase, da nam ni bilo potrebno pisati na dolgo in široko. Namesto studenti v vrstici where smo tako lahko napisali s.<atribut>, namesto izpit pa i.<atribut>.

Poiščimo vse študente, ki imajo svoj rojstni datum višji od minimalnega rojstnega datuma (se pravi so rojeni kasneje).

mysql> SELECT idst, ime, priimek, d_roj

-> FROM studenti

-> WHERE d_roj > ( SELECT MIN(d_roj)

-> FROM studenti);

+------+---------+----------+------------+

| idst | ime | priimek | d_roj |

+------+---------+----------+------------+

| 1 | Tjasa | Kopicnik | 1987-12-01 |

| 2 | Domen | Prebel | 1987-11-02 |

| 3 | Tjasa | Koper | 1986-10-03 |

| 4 | Zlatko | Dren | 1988-12-02 |

| 5 | Zdravko | Dren | 1989-03-15 |

| 6 | Tjasa | Cepel | 1986-01-01 |

| 8 | Tim | Andolsek | 1986-08-09 |

+------+---------+----------+------------+

7 rows in set (0.00 sec)

Naš rezultat smo dobili tako, da smo gnezdili SQL stavke. SQL stavki niso nujno sestavljeni iz enega samega stavka, ampak jih lahko gnezdimo. Splošen primer pri izgledal takole: SELECT <atribut> <atribut> <atribut> ...

FROM <ime tabele>

WHERE <atribut> <operator> ( SELECT ... WHERE ... FROM );

Naši SQL stavki so do sedaj izgledali takole:

SELECT <atributi>

FROM <tabele>

WHERE pogoj;

Pri taki sintaksi bi naleteli na teţavo pri sledeči nalogi. Ţeleli bi izpisati vse izpite in njihovo minimalno število polaganj. Pri tem nam pride v pomoč razširjen SQL stavek, ki pa v osnovi izgleda takole:

Page 39: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

39

(a)SQL FRI

Edition

SELECT <atributi>

FROM <tabele>

WHERE pogoj

GROUP BY <atributi> -- Grupiranje po atributih

HAVING <atribut> -- Selekcija po skupinah

Če sedaj da razširjen stavek uporabimo:

mysql> SELECT izpit, MIN(stp)

-> FROM izpiti

-> GROUP BY izpit;

+-------+----------+

| izpit | MIN(stp) |

+-------+----------+

| ANA1 | 1 |

| DS | 2 |

| OP1 | 2 |

| OP2 | 4 |

| OPB | 6 |

| PB | 0 |

+-------+----------+

6 rows in set (0.09 sec)

Naša naslednja naloga bo izpisati vse študente, ki so vpisani izredno.

mysql> SELECT idst, ime, priimek, idvp, ri

-> FROM studenti s, vpisi v

-> WHERE s.idst = v.idvp AND ri = 'IZR';

+------+--------+----------+------+------+

| idst | ime | priimek | idvp | ri |

+------+--------+----------+------+------+

| 3 | Tjasa | Koper | 3 | IZR |

| 4 | Zlatko | Dren | 4 | IZR |

| 8 | Tim | Andolsek | 8 | IZR |

+------+--------+----------+------+------+

3 rows in set (0.11 sec)

Sedaj pa dajmo stvari malce zakomplicirati. Še vedno ţelimo izpisati vse študente, ki so vpisani izredno, poleg tega pa so polagali katerikoli izpit vsaj dvakrat.

mysql> SELECT idst, ime, priimek, idvp, ri, idiz, stp

-> FROM studenti s, vpisi v, izpiti i

-> WHERE s.idst = v.idvp AND s.idst = i.idiz

-> AND v.ri = 'IZR' AND stp >= 2;

+------+--------+---------+------+------+------+------+

| idst | ime | priimek | idvp | ri | idiz | stp |

+------+--------+---------+------+------+------+------+

| 4 | Zlatko | Dren | 4 | IZR | 4 | 2 |

+------+--------+---------+------+------+------+------+

1 row in set (0.00 sec)

Uporabili smo zopet isti trik kot prej. Enačili smo idje študentov z njihovimi pravilnimi idji izpitov in vpisov. Potem so nam ostali le še pogoji za primerjavo. Naša nova naloga je izpisati imena in priimke vseh študentov, katerih število polaganj kateregakoli izpita je večja od povprečnega števila polaganj vseh študentov.

Page 40: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

40

(a)SQL FRI

Edition

Najprej bi izračunali, koliko je povprečno število polaganj (samo informativno). mysql> SELECT AVG(stp) AS 'Povprecno stevilo polaganj' FROM izpiti;

+----------------------------+

| Povprecno stevilo polaganj |

+----------------------------+

| 2.6250 |

+----------------------------+

1 row in set (0.01 sec)

Sedaj pa še napšimo konkretno poizvedbo.

mysql> SELECT idst, ime, priimek, idiz, stp

-> FROM studenti s, izpiti i

-> WHERE s.idst = i.idiz AND i.stp > ( SELECT AVG(stp)

-> FROM izpiti );

+------+---------+---------+------+------+

| idst | ime | priimek | idiz | stp |

+------+---------+---------+------+------+

| 5 | Zdravko | Dren | 5 | 4 |

| 6 | Tjasa | Cepel | 6 | 5 |

| 7 | Metka | Medved | 7 | 6 |

+------+---------+---------+------+------+

3 rows in set (0.05 sec)

Kot v eni izmed prejšnjih nalog, smo tudi tokrat gnezdili SQL stavke. Najprej smo enačili id stolpce študentov in izpitov, potem smo pa še posebej izračunali da naj po število polaganj višje od povprečnega števila polaganj.

Page 41: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

41

(a)SQL FRI

Edition

7. MYSQL QUERY BROWSER Osnovne ukaze smo ţe obdelali v komandni vrstici. Da se pa ne bi počutili preveč hekersko in kleli ob tem, ko smo stisnili enter, preden smo pregledali, če smo napisali pravo vrstico, bomo pa namestili MySQL GUI orodja. Ta orodja niso nič drugega kot uporabniku prijaznejše okolje za izvajanje MySQL ukazov. Za namestitev orodij obiščite stran http://dev.mysql.com/downloads/gui-tools/5.0.html in si downloadajte datoteko za vaš operacijski sistem, poţenite, in samo klikajte »Next«. Podrobnejše si bomo pogledali MySQL Query Browser. Zaţenite MySQL Query Browser. Pojavilo se vam bo okno, kamor morate vpisati vpisne podatke. Kot »Server host« vpišite »localhost«, za username root, za geslo pa vaše geslo. Pod »default schema« vpišite vaje (to je naša baza, ki jo bomo obdelovali po defaultu).

Pojavil se vam bo takšen vmesnik. Najprej desno kliknite na »Result set 1« in kliknite rename. Preimenujte v Vaje.

Poglejmo si malce kako izgleda uporabniški vmesnik programa.

Page 42: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

42

(a)SQL FRI

Edition

Pod številko ena se nahaja okno za vpis ukazov. V njega vpišemo ukaz (tako kot v komandni vrstici, kadar smo prijavljeni v MySQL). Ukaz izvedemo s pomočjo gumba »Execute«. Izvajanje ukaza pa ustavimo z »Stop«. Številka dva nam prikazuje naše baze, tabele v bazah in atribute. Ključi so označeni z simbolom za ključ. Številka tri je prikazno okno. Ko ukaz izvedemo, se nam bo izpisal rezultat. Pod štiri pa imamo majhno knjiţico pomoči.

Dajmo za naše prvo dejanje izpisati tabelo otrok. V polje vpišimo

Page 43: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

43

(a)SQL FRI

Edition

SELECT * FROM otroki;

Kliknemo na gumb »Execute« in v polju za izpis bi se nam moralo prikazati sledeče:

Seveda pa je GUI vmesnik namenjen poenostavljanju. Če dvakrat kliknemo na tabelo delavci, nam bo vmesnik avtomatsko napisal kodo. Vse kar moramo narediti je pritisniti na gumb »Execute« in zgodilo se bo sledeče:

Če pritisnemo tipko F11, se nam bo pokazal vmesnik, ki oštevilčuje SQL vrstice in ponuja še nekaj dodatnih bombončkov. Vaš vmesnik biti sedaj podoben:

Page 44: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

44

(a)SQL FRI

Edition

Če pogledamo podrobneje zgoraj vrstico prikazano na spodnji sliki, bomo opazili različne gumbe kot so select, from, group, having itd. Če z miškinim kurzorjem kliknemo na select in potem izberemo o_ime in o_priimek nam bo GUI avtomatsko v vrstico vpisal sledeče: SELECT o.`o_ime`, o.`o_priimek` FROM otroki o

Če pa sedaj stisnemo še execute, pa dobimo izpis vseh otrok (imena in priimki):

Page 45: (a)SQL - Shrani.si · Skripta je prosto dostopna in se jo lahko tiska, pošilja naprej ipd., edina zahteva je, da ostane nespremenjena. Seveda skripta verjetno ni brez napak, tako

Boštjan Cigan

© 2008 Boštjan Cigan

45

(a)SQL FRI

Edition

LITERATURA

MySQL Developers Library 4th Edition, Dubois P., Addison-Wesley Professional (2008)

MySQL Query Browser Manual, Več avtorjev, MySQL AB (2008), Dostopno na naslovu: http://downloads.mysql.com/docs/query-browser-en.a4.pdf

SQL Podatkovni tipi (29.11.2008, 13:25), Dostopno na naslovu: http://www.ispirer.com/doc/sqlways38/Output/SQLWays-1-190.html