Bazy danych 4. Przykłady SQL – podstawy

advertisement
Bazy danych
4. Przykłady
SQL – podstawy
P. F. Góra
http://th-www.if.uj.edu.pl/zfs/gora/
2011/12
Przykład I
Przedsiebiorca
˛
tworzy baz˛e danych pracowników na potrzeby wypłacania im wynagrodzeń i przekazywania zaliczek do Urz˛edu Skarbowego. Zachodza˛ naste˛
pujace
˛ zależności funkcyjne:
PracId → Stanowisko
Stanowisko → Stawka
PracId → StażPracy
StażPracy Stawka → Wynagrodzenie
PracId → Gmina
Gmina → UrzadSkarbowy
˛
c 2010-11 P. F. Góra
Copyright (1a)
(1b)
(1c)
(1d)
(1e)
(1f)
4–2
1. Udowodnić, że PracId → Wynagrodzenie
PracId → Stanowisko ∧ Stanowisko → Stawka =⇒ PracId → Stawka (2a)
PracId → Stawka ∧ PracId → StażPracy =⇒ PracId → StażPracy Stawka
(2b)
PracId → StażPracy Stawka ∧ StażPracy Stawka → Wynagrodzenie
=⇒ PracId → Wynagrodzenie
(2c)
2. Spróbujmy zaprojektować taka˛ oto tabele:
˛
Pracownik (PracId, StażPracy, Stanowisko, Stawka, Gmina)
(3)
Tabela (??) nie jest w 3PN, gdyż zawiera relacje˛ przechodnia˛ (do atrybutu nie
bed
˛ acego
˛
cz˛eścia˛ klucza). Ponieważ stawka przyporzadkowana
˛
jest stanowisku, nie zaś konkretnemu pracownikowi, wpisywanie stawek jak w (??) prowadzi do redundancji i anomalii modyfikacji.
c 2010-11 P. F. Góra
Copyright 4–3
3. Nastepuj
˛ acy
˛ projekt jest w 3PN, a nawet w PNBC
Pracownicy (PracId, StażPracy, Stanowisko, Gmina)
(4a)
Stanowiska (Stanowisko, Stawka)
(4b)
Płace StażPracy, Stawka, Wynagrodzenie
(4c)
˛
Urz˛edy (Gmina, UrzadSkarbowy
)
(4d)
4. W opraciu o projekt (??), w jezyku
˛
algebry relacji sformułować zapytanie
o wynagrodzenie konkretnego pracownika
ρT1 πStanowisko,StażPracy,Wynagrodzenie (Stanowiska 1 Płace)
πPracId,Wynagrodzenie (T1 1 Pracownicy)
(5a)
(5b)
Sa˛ inne możliwe ścieżki wykonania tego zapytania.
c 2010-11 P. F. Góra
Copyright 4–4
Przykład II
Kancelaria adwokacka prowadzi baz˛e czynności adwokackich. Każda czynność
wykonana jest przez pracownika na jakimś stanowisku; ze stanowiskiem zwia˛
zana jest stawka. Każda czynność wykonana jest na rzecz pewnego klienta.
Cena, jaka˛ płaci klient, zależy od czasu trwania czynności adwokackiej i stawki,
jaka˛ pobiera pracownik kancelarii.
Zależności funkcyjne:
PracId → Stanowisko
Stanowisko → Stawka
Czynność → Pracownik KlientId Czas
Czas Stawka → Koszt
KlientId → NazwaKlienta
c 2010-11 P. F. Góra
Copyright (6a)
(6b)
(6c)
(6d)
(6e)
4–5
Tabele:
Czynności Czynność, PracId, KlientId, Czas
(7a)
Pracownicy (PracId, Stanowisko)
(7b)
Stanowiska (Stanowisko, Stawka)
(7c)
Opłaty (Czas, Stawka, Koszt)
(7d)
Kilenci (KlientId, NazwaKlienta)
(7e)
Mimo iż po zdefiniowaniu osobnych tabel Pracownicy i Stanowiska tabel jest
wiecej,
˛
łacznie
˛
przechowujemy mniej informacji.
c 2010-11 P. F. Góra
Copyright 4–6
Przykład III
Tworzymy baz˛e opisujac
˛ a˛ zaliczenia, jakie studenci uzyskiwali ze swoich projektów. Jeden student może podchodzić do tego samego projektu wiele razy (może
poprawiać ocene).
˛ Jednego dnia jeden student może starać sie˛ tylko o jedno zaliczenie.
NrZaliczenia → NrIndeksu NrProjektu Data Ocena
(8a)
NrIndeksu Data → NrZaliczenia
(8b)
Wydaje sie,
˛ że projekt
Zaliczenia (NrZaliczenia, NrIndeksu, Data, NrProjektu, Ocena)
(9)
nie jest poprawny, gdyż nie uwzglednia
˛
drugiej z zależności (??).
c 2010-11 P. F. Góra
Copyright 4–7
Projekt
Zaliczenia (NrZaliczenia, NrIndeksu, Data, NrProjektu, Ocena)
(10)
nie jest poprawny, gdyż zawiera zależności przechodnie:
NrIndeksu Data → NrZaliczenia → NrProjektu Ocena, a zatem nie jest w 3PN
(ustaliliśmy, że NrZaliczenia nie może być kluczem!).
c 2010-11 P. F. Góra
Copyright 4–8
Rozbijmy pierwsza˛ z zależności funkcyjnych (??)na dwie cz˛eści:
NrZaliczenia → NrProjektu Ocena
(11a)
NrZaliczenia → NrIndeksu Data
(11b)
NrIndeksu Data → NrZaliczenia
(11c)
Zależności (??), (??) sa˛ swoimi odwrotnościami, a zatem jedna˛ z nich można
wyeliminować.
Projekt
KtoKiedy (NrIndeksu, Data, NrZaliczenia)
(12a)
CoZaCo (NrZaliczenia, NrProjektu, Ocena)
(12b)
jest w PNBC. Ta analiza pokazuje, że projekt (??) tak naprawde˛ jest poprawny .
c 2010-11 P. F. Góra
Copyright 4–9
Przykład IV∗
Fabryka w magazynie przechowuje cz˛eści różnego typu (śrubki i nakretki).
˛
Każda cz˛eść ma swój unikalny identyfikator. W magazynie każdy pojemnik („regał”) zawiera identyczne cz˛eści. Mamy relacje funkcyjne
Śrubki:
Nakretki:
˛
NrRegału → IdCz˛eści Ilość
(13a)
IdCz˛eści → Długość Średnica TypŁba
(13b)
IdCz˛eści → Średnica
(13c)
Projekty odpowiednich tabel sa˛ (pozornie) oczywiste.
c 2010-11 P. F. Góra
Copyright 4–10
Niektóre zapytania bardzo wykonać jest bardzo łatwo, na przykład wskaż regały,
w których znajduja˛ sie˛ śrubki o długości 3/4":
πNrRegału πIdCz˛eści σDługość=3/4"Śrubki
1 Regały
(14)
Inne zapytania sa˛ bardziej problematyczne — na przykład jaki typ łba maja˛
śrubki przechowywane na regale 58
πTypŁba
σNrRegału=58Regały
1 Śrubki
(15)
To zapytanie powinno zadziałać dobrze: Jeśli cz˛eści przechowywane na regale
58 sa˛ śrubkami, wszystko jest OK. Jeśli cz˛eści przechowywane na regale 58 nie
sa˛ śrubkami (tylko nakretkami),
˛
złaczenie
˛
w (??) da zbiór pusty, a wiec
˛ także OK
— pod warunkiem, że nie przypiszemy tego samego IdCz˛eści śrubkom i nakret˛
kom, a takiego wiezu
˛ w naszym projekcie nie ma.
c 2010-11 P. F. Góra
Copyright 4–11
Problem można cz˛eściowo rozwiazać
˛
modyfikujac
˛ tabele˛ Regały:
NrRegału → IdCz˛eści RodzajCz˛eści Ilość
(16)
Wówczas możliwe jest sprawdzenie na których regałach znajduja˛ sie˛ śrubki
ρRegałyŚrubek σRodzajCz˛eści=’Śrubki’Regały
(17)
i dalej
πTypŁba
σNrRegału=58RegałyŚrubek
1 Śrubki
(18)
Jeśli na regale 58 nie ma śrubek, dostaniemy zbiór pusty.
c 2010-11 P. F. Góra
Copyright 4–12
W relacyjnym modelu danych nie ma “rekordów z wariantami”, zanych z niektórych jezyków
˛
programowania.
Prawdziwym rozwiazaniem
˛
byłoby przekonanie zleceniodawcy, że stosowanie
jednolitej numeracji do różnego rodzaju cz˛eści nie jest rozsadne.
˛
Jeżeli nie da sie˛ zleceniodawcy do tego przekonać — a zleceniodawca może
mieć uzasadnione powody aby protestować — najlepszym rozwiazaniem
˛
jest
zsumowanie zależności (??), (??), które maja˛ ten sam poprzednik:
NrRegału → IdCz˛eści Ilość
IdCz˛eści → Długość Średnica TypŁba
(19a)
(19b)
Atrybut Średnica wystepuje
˛
w nastepnikach
˛
dwa razy, wiec
˛ po zsumowaniu pojawia sie˛ tylko raz. Teraz należy rozumieć, że jeżeli atrybuty Długość, TypŁba
przyjmuja˛ wartość null, mamy do czynienia z nakretk
˛ a,
˛ w przeciwnym zaś razie ze śrubka.
˛
c 2010-11 P. F. Góra
Copyright 4–13
Zgodnie z zasadami sztuki, funkcja określajaca
˛ czy dana cz˛eść jest śrubka,
˛ czy
nakretk
˛ a,
˛ powinna być wbudowana w baz˛e danych (jako tak zwana procedura
składowana).
Podobnie w bazie powinien znaleźć sie˛ wiez
˛ domenowy (check) stwierdzajacy,
˛
że atrybuty Długość, TypŁba musza˛ być jednocześnie null lub not null.
Atrybut Średnica powinien być zawsze not null.
c 2010-11 P. F. Góra
Copyright 4–14
Przykład V (kolejowy)
Tworzymy baz˛e danych zawierajac
˛ a˛ (uproszczony) rozkład jazdy pociagów
˛
oraz
informacje o sprzedanych biletach.
Po pierwsze,
• Z każdym pociagiem
˛
stowarzyszona jest lista stacji, na których sie˛ on zatrzymuje.
• Z każda˛ stacja˛ stowarzyszony jest zbiór pociagów,
˛
na których sie˛ on zatrzymuje.
• Dla każdej stacji należy podać godziny przyjazdu i odjazdu każdego pocia˛
gu, który sie˛ na niej zatrzymuje.
c 2010-11 P. F. Góra
Copyright 4–15
Pierwszy i ostatni punkt odpowiadaja˛ nastepuj
˛ acym
˛
zależnościom funkcyjnym:
NrPociagu
˛ Stacja → NrKolejny
(20a)
NrPociagu
˛ Stacja → Przyjazd Odjazd
(20b)
co prowadzi do nastepuj
˛ acej
˛ struktury tabeli
Stacja, NrKolejny, Przyjazd, Odjazd
Przystanki NrPociagu,
˛
(21)
Powstaje jednak pewna watpliwość:
˛
A co sie˛ stanie jeśli jakiś pociag
˛ nie przejeżdża przez dana˛ stacje?
˛ Czy przypoadkiem zależności funkcyjne (??) nie wymagaja˛ wyspecyfikowania wszystkich możliwych par NrPociagu-Stacja?
˛
Oczywiście nie: Zależność funkcyjna ma postać implikacji: jeżeli podamy atrybuty
poprzednika, to ustalamy jednoznacznie wartości atrybutów nastepnika.
˛
A jeżeli
nie, to nie ,.
c 2010-11 P. F. Góra
Copyright 4–16
Rola zapytań
A co z określeniem zbioru pociagów,
˛
które zatrzymuja˛ sie˛ na danej stacji? Nie
trzeba w tym celu konstruować osobnej tabeli (relacji) — można to osiagn
˛ ać
˛
poprzez odpowiednie zapytanie:
πNrPociagu
σStacja=’Koluszki’ (Przystanki)
˛
(22)
Nie wszystkie informacje przechowuje sie˛ w postaci osobnych tabel —
użyteczność baz danych polega (miedzy
˛
innymi) na tym, że wiele rzeczy da sie˛
zrealizować poprzez zapytania.
c 2010-11 P. F. Góra
Copyright 4–17
Zadanie
Posługujac
˛ sie˛ schematem tabeli Przystanki (??), znaleźć wszystkie pociagi,
˛
które przejeżdżaja˛ przez stacje˛ X oraz przez stacje˛ Y.
πNrPociagu
σStacja=’X’ (Przystanki) 1 πNrPociagu
σStacja=’Y’ (Przystanki)
˛
˛
(23)
Tabela Przystanki wystepuje
˛
w powyższym zapytaniu dwa razy, po obu stronach
złaczenia.
˛
Jest to przykład tak zwanego samozłaczenia
˛
(self-join).
c 2010-11 P. F. Góra
Copyright 4–18
Zadanie∗
Posługujac
˛ sie˛ schematem tabeli Przystanki (??), znaleźć wszystkie pociagi,
˛
które najpierw przejeżdżaja˛ przez stacje˛ X, później przez stacje˛ Y.
h
i
(24a)
h
i
(24b)
ρStacjaX(NrPociagu,NrX)
πNrPociagu,NrKolejny
σStacja=’X’ (Przystanki)
˛
˛
ρStacjaY(NrPociagu,NrY)
πNrPociagu,NrKolejny
σStacja=’Y’ (Przystanki)
˛
˛
πNrPociagu
σNrX<NrY (StacjaX 1 StacjaY)
˛
(24c)
Zapytanie (??) oczywiście także zawiera samozłaczenie,
˛
tyle że w formie niejawnej.
Pytanie: Po jakim atrybucie realizowane jest złaczenie
˛
w (??)? Po atrybucie
NrPociagu,
˛
bo to jest powtarzajacy
˛ sie˛ atrybut w tabelach StacjaX, StacjaY.
c 2010-11 P. F. Góra
Copyright 4–19
Structured Query Language
Używane standardy:
• SQL92
• SQL99
• SQL:2003
Żaden dostawca nie jest w pełni zgodny ze standardem — prawie wszyscy wprowadzaja˛ rozszerzenia, prawie nikt nie spełnia wszystkich wymogów. W dużych
systemach komercyjnych odejście od wymogów nie jest wielkie
c 2010-11 P. F. Góra
Copyright 4–20
Programowanie deklaratywne
SQL — a ściślej, podzbiór SQL obejmujacy
˛ zapytania SELECT — jest jezy˛
kiem deklaratywnym: określa logik˛e programowania, bez określenia control flow.
Innymi słowy, zapytanie SQL mówi co chcemy osiagn
˛ ać,
˛ bez określenia jak
chcemy to zrobić.
Przeciwieństwem deklaratywnego paradygmatu programowania jest programowanie imperatywne.
c 2010-11 P. F. Góra
Copyright 4–21
Połaczenie
˛
sie˛ z serwerem
Przed rozpocz˛eciem pracy, nalezy wywołać proces kliencki, który połaczy sie˛ z
serwerem. W MySQL może to wygladać
˛
na przykład tak:
C:\>mysql -upawel -p
Enter password: *************
Po zakończeniu pracy trzeba sie˛ pożegnać:
mysql> QUIT;
Bye
Znacznie cz˛eściej połaczenie
˛
z serwerem nawiazuje
˛
sie˛ za pomoca˛ jakiejś aplikacji, nie zaś bezpośrednio z shella.
c 2010-11 P. F. Góra
Copyright 4–22
Utworzenie bazy danych
mysql> CREATE DATABASE MoiStudenci CHARACTER SET cp1250;
Query OK, 1 row affected (0.06 sec)
mysql> USE MoiStudenci;
Database changed
mysql>
Po wywołaniu klienta, trzeba “wejść” do wybranej bazy za pomoca˛ instrukcji USE
— nie tylko po jej utworzeniu, ale zawsze.
c 2010-11 P. F. Góra
Copyright 4–23
To, jakie bazy znajduja˛ sie˛ na serwerze, możemy zobaczyć za pomoca˛ instrukcji
SHOW DATABASES.
mysql> SHOW DATABASES;
+--------------------+
| Database
|
+--------------------+
| information_schema |
| kaskady
|
| moistudenci
|
| mysql
|
| test
|
+--------------------+
5 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–24
Utworzenie tabeli
mysql> CREATE TABLE Studenci
-> (NrStudenta SMALLINT UNSIGNED NOT NULL
-> AUTO_INCREMENT PRIMARY KEY);
Query OK, 0 rows affected (0.14 sec)
Jeśli okaże sie˛ to konieczne, po utworzeniu można zmienić definicje˛ tabeli.
mysql> ALTER TABLE Studenci
-> ADD COLUMN (Nazwisko VARCHAR(20) NOT NULL);
Query OK, 1 row affected (0.17 sec)
Records: 1 Duplicates: 0 Warnings: 0
c 2010-11 P. F. Góra
Copyright 4–25
Składnia polecenia CREATE TABLE
CREATE TABLE NazwaTabeli (
NazwaKolumny1 TypKolumny1 NULL | NOT NULL . . . ,
NazwaKolumny2 TypKolumny2 NULL | NOT NULL . . . ,
...
)
PRIMARY KEY (NazwaKolumnyp,NazwaKolumnyq ,. . . )
;
Inne opcje poznamy później.
c 2010-11 P. F. Góra
Copyright 4–26
Typy danych (atrybutów)
TINYINT
SMALLINT
MEDIUMINT
INT
INTEGER
BIGINT
REAL
DOUBLE
FLOAT
DECIMAL
NUMERIC
c 2010-11 P. F. Góra
Copyright DATE
TIME
TIMESTAMP
DATETIME
CHAR
VARCHAR
BOOLEAN
TINYBLOB
BLOB
MEDIUMBLOB
LONGBLOB
TINYTEXT
TEXT
LONGTEXT
ENUM
SET
4–27
Instrukcja DESCRIBE podaje definicje˛ tabeli.
mysql> DESCRIBE Studenci;
+------------+----------------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+------------+----------------------+------+-----+---------+----------------+
| NrStudenta | smallint(5) unsigned | NO
| PRI | NULL
| auto_increment |
| Nazwisko
| varchar(20)
| NO
|
|
|
|
+------------+----------------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
Niepotrzebna˛ tabele˛ usuwamy za pomoca˛ instrukcji DROP TABLE.
mysql> DROP TABLE Studenci;
Query OK, 0 rows affected (0.02 sec)
Lepiej ja˛ utworzyć od poczatku
˛
dobrze niż dodawać kolumna po kolumnie. . . ,
c 2010-11 P. F. Góra
Copyright 4–28
mysql> CREATE TABLE Studenci
-> (NrStudenta SMALLINT UNSIGNED NOT NUll
-> AUTO_INCREMENT PRIMARY KEY,
-> Imie VARCHAR(20),
-> Nazwisko VARCHAR(20) NOT NULL,
-> Uwagi VARCHAR(30),
-> Grupa CHAR(2) NOT NULL));
Query OK, 0 rows affected (0.06 sec)
mysql> DESCRIBE Studenci;
+------------+----------------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+------------+----------------------+------+-----+---------+----------------+
| NrStudenta | smallint(5) unsigned | NO
| PRI | NULL
| auto_increment |
| Imie
| varchar(20)
| YES |
| NULL
|
|
| Nazwisko
| varchar(20)
| NO
|
|
|
|
| Uwagi
| varchar(30)
| YES |
| NULL
|
|
| Grupa
| char(2)
| NO
|
|
|
|
+------------+----------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–29
Wstawianie wartości do tabeli
mysql> SET CHARACTER SET cp1250;
Query OK, 0 rows affected (0.00 sec)
Gdybyśmy tego nie zrobili, MySQL używałby takiego zestawu znaków, jaki obowiazywał
˛
domyślnie w momencie połaczenia
˛
z serwerem. Kwestie określania
zestawu znaków to osobliwość MySQLa /
mysql> INSERT INTO Studenci VALUES
-> (1,’Milena’,’Zahorska’,’wt’,’uzupełniajace’);
˛
Query OK, 1 row affected (0.02 sec)
c 2010-11 P. F. Góra
Copyright 4–30
Co teraz jest w tabeli?
mysql> SELECT * FROM Studenci;
+------------+--------+----------+---------------+-------+
| NrStudenta | Imie
| Nazwisko | Uwagi
| Grupa |
+------------+--------+----------+---------------+-------+
|
1 | Milena | Zahorska | uzupełniajace
˛
| wt
|
+------------+--------+----------+---------------+-------+
1 row in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–31
Składnia zapytania SELECT;
SELECT [DISTINCT] lista select
FROM tabela lub zapytanie
WHERE warunek logiczny
GROUP BY wyrażenie grupujace
˛
HAVING warunek wyszukiwania po grupowaniu
ORDER BY wyrażenie porzadkuj
˛
ace
˛ [ASC | DESC]
;
W zapytaniu SELECT wszystkie klauzule musza˛ wystepować
˛
w powyższej kolejności. Niektóre klauzule można opuścić, ale to, co jest, musi być w tej kolejności.
c 2010-11 P. F. Góra
Copyright 4–32
Dodajmy wiecej
˛
danych
mysql> INSERT INTO Studenci VALUES
-> (2,’Sylwester’,’Tomiec’,’uzupełniajace’,’wt’),
˛
-> (3,’Michał’,’Gajewczyk’,’’’’,’wt’);
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM Studenci;
+------------+-----------+-----------+---------------+-------+
| NrStudenta | Imie
| Nazwisko | Uwagi
| Grupa |
+------------+-----------+-----------+---------------+-------+
|
1 | Milena
| Zahorska | uzupełniajace
˛
| wt
|
|
2 | Sylwester | Tomiec
| uzupełniajace
˛
| wt
|
|
3 | Michał
| Gajewczyk | ’
| wt
|
+------------+-----------+-----------+---------------+-------+
3 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–33
Wykorzystanie opcji AUTOINCREMENT
mysql> INSERT INTO Studenci (Imie,Nazwisko,Grupa) VALUES
-> (’Rafał’,’Świderski’,’wt’),
-> (’Maciej’,’Matowicki’,’wf’),
-> (’Janko’,’Muzykant’,’nd’);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM Studenci;
+------------+-----------+-----------+---------------+-------+
| NrStudenta | Imie
| Nazwisko | Uwagi
| Grupa |
+------------+-----------+-----------+---------------+-------+
|
1 | Milena
| Zahorska | uzupełniajace
˛
| wt
|
|
2 | Sylwester | Tomiec
| uzupełniajace
˛
| wt
|
|
3 | Michał
| Gajewczyk | ’
| wt
|
|
4 | Rafał
| Świderski | NULL
| wt
|
|
5 | Maciej
| Matowicki | NULL
| wf
|
|
6 | Janko
| Muzykant | NULL
| nd
|
+------------+-----------+-----------+---------------+-------+
6 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–34
Zapytanie UPDATE
mysql> UPDATE Studenci
-> SET Uwagi=NULL
-> WHERE NrStudenta=3;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> UPDATE Studenci
-> SET Grupa=’wt’ WHERE Grupa=’wf’;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
c 2010-11 P. F. Góra
Copyright 4–35
mysql> SELECT * FROM Studenci;
+------------+-----------+-----------+---------------+-------+
| NrStudenta | Imie
| Nazwisko | Uwagi
| Grupa |
+------------+-----------+-----------+---------------+-------+
|
1 | Milena
| Zahorska | uzupełniajace
˛
| wt
|
|
2 | Sylwester | Tomiec
| uzupełniajace
˛
| wt
|
|
3 | Michał
| Gajewczyk | NULL
| wt
|
|
4 | Rafał
| Świderski | NULL
| wt
|
|
5 | Maciej
| Matowicki | NULL
| wt
|
|
6 | Janko
| Muzykant | NULL
| nd
|
+------------+-----------+-----------+---------------+-------+
6 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–36
Zapytanie DELETE
Usuwanie wierszy spełniajacych
˛
podane kryterium:
mysql> DELETE FROM Studenci
-> WHERE Imie=’Janko’;
Query OK, 1 row affected (0.03 sec)
Dodajmy coś jeszcze:
mysql> INSERT INTO Studenci (Imie,Nazwisko,Grupa) VALUES
-> (’Michał’,’Czubek’,’pt’),(’Marcin’,’Pyra’,’pt’),
-> (’Marcin’,’Baranowski’,’pt’);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
c 2010-11 P. F. Góra
Copyright 4–37
mysql> SELECT * FROM Studenci;
+------------+-----------+------------+---------------+-------+
| NrStudenta | Imie
| Nazwisko
| Uwagi
| Grupa |
+------------+-----------+------------+---------------+-------+
|
1 | Milena
| Zahorska
| uzupełniajace
˛
| wt
|
|
2 | Sylwester | Tomiec
| uzupełniajace
˛
| wt
|
|
3 | Michał
| Gajewczyk | NULL
| wt
|
|
4 | Rafał
| Świderski | NULL
| wt
|
|
5 | Maciej
| Matowicki | NULL
| wt
|
|
7 | Michał
| Czubek
| NULL
| pt
|
|
8 | Marcin
| Pyra
| NULL
| pt
|
|
9 | Marcin
| Baranowski | NULL
| pt
|
+------------+-----------+------------+---------------+-------+
8 rows in set (0.01 sec)
Brakuje numeru ’6’ — AUTOINCREMENT “zapamietał”,
˛
że on tam był.
AUTOINCREMENT zawsze startuje od high water mark.
c 2010-11 P. F. Góra
Copyright 4–38
Jawnie wyspecyfikowana lista select
mysql> SELECT Imie, Nazwisko FROM Studenci;
+-----------+------------+
| Imie
| Nazwisko
|
+-----------+------------+
| Milena
| Zahorska
|
| Sylwester | Tomiec
|
| Michał
| Gajewczyk |
| Rafał
| Świderski |
| Maciej
| Matowicki |
| Michał
| Czubek
|
| Marcin
| Pyra
|
| Marcin
| Baranowski |
+-----------+------------+
8 rows in set (0.01 sec)
Gwiazdka w zapytaniu SELECT (SELECT * FROM...) oznacza “wszystkie kolumny”.
c 2010-11 P. F. Góra
Copyright 4–39
Problem duplikatów
mysql> SELECT Imie
-> FROM Studenci;
+-----------+
| Imie
|
+-----------+
| Milena
|
| Sylwester |
| Michał
|
| Rafał
|
| Maciej
|
| Michał
|
| Marcin
|
| Marcin
|
+-----------+
8 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright mysql> SELECT DISTINCT Imie
-> FROM Studenci;
+-----------+
| Imie
|
+-----------+
| Milena
|
| Sylwester |
| Michał
|
| Rafał
|
| Maciej
|
| Marcin
|
+-----------+
6 rows in set (0.00 sec)
4–40
Operator LIKE
mysql> SELECT Imie, Nazwisko
-> FROM Studenci
-> WHERE Imie LIKE ’Mi%’;
+--------+-----------+
| Imie
| Nazwisko |
+--------+-----------+
| Milena | Zahorska |
| Michał | Gajewczyk |
| Michał | Czubek
|
+--------+-----------+
3 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright mysql> SELECT Imie, Nazwisko
-> FROM Studenci
-> WHERE Imie LIKE ’%ł’;
+--------+-----------+
| Imie
| Nazwisko |
+--------+-----------+
| Michał | Gajewczyk |
| Rafał | Świderski |
| Michał | Czubek
|
+--------+-----------+
3 rows in set (0.00 sec)
4–41
Wykorzystanie ORDER BY
mysql> SELECT Imie, Nazwisko
-> FROM Studenci
-> WHERE Grupa=’wt’
-> ORDER BY Nazwisko ASC;
+-----------+-----------+
| Imie
| Nazwisko |
+-----------+-----------+
| Michał
| Gajewczyk |
| Maciej
| Matowicki |
| Sylwester | Tomiec
|
| Milena
| Zahorska |
| Rafał
| Świderski |
+-----------+-----------+
5 rows in set (0.02 sec)
Problemy z poprawnym sortowaniem polskich znaków diakrytycznych /
c 2010-11 P. F. Góra
Copyright 4–42
MySQL i programowanie wsadowe
C:\wyklady\bazy> mysql < nazwa pliku
C:\wyklady\bazy> mysql -hhostname -uusername -p < nazwa pliku
Plik musi być dostepny
˛
dla klienta.
Pliki wsadowe można też wołać “z wnetrza”
˛
klienta:
mysql> source nazwa pliku;
Uwaga: Jeśli któreś polecenie w pliku wsadowym spowoduje bład,
˛ dalsze polecenia nie sa˛ wykonywane.
c 2010-11 P. F. Góra
Copyright 4–43
Tworzenie tabeli wraz z kopiowaniem danych
mysql> USE moistudenci;
Database changed
mysql> DESCRIBE Studenci;
+------------+----------------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+------------+----------------------+------+-----+---------+----------------+
| NrStudenta | smallint(5) unsigned | NO
| PRI |
| auto_increment |
| Imie
| varchar(20)
| NO
|
|
|
|
| Nazwisko
| varchar(20)
| NO
|
|
|
|
| Uwagi
| varchar(30)
| YES |
|
|
|
| Grupa
| char(2)
| YES |
|
|
|
+------------+----------------------+------+-----+---------+----------------+
5 rows in set (0.21 sec)
c 2010-11 P. F. Góra
Copyright 4–44
mysql> CREATE TABLE Studenci2
-> (NrStudenta INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Imie VARCHAR(20) NOT NULL, Nazwisko VARCHAR(20) NOT NULL,
-> Uwagi VARCHAR(30), Grupa CHAR(2))
-> -- TU kończy si˛
e definicja tabeli!
-> SELECT * FROM STUDENCI;
Query OK, 9 rows affected (1.08 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql> DESCRIBE Studenci2;
+------------+------------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+------------+------------------+------+-----+---------+----------------+
| NrStudenta | int(10) unsigned | NO
| PRI |
| auto_increment |
| Imie
| varchar(20)
| NO
|
|
|
|
| Nazwisko
| varchar(20)
| NO
|
|
|
|
| Uwagi
| varchar(30)
| YES |
|
|
|
| Grupa
| char(2)
| YES |
|
|
|
+------------+------------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
c 2010-11 P. F. Góra
Copyright 4–45
mysql> SELECT * FROM Studenci2;
+------------+----------+--------------+-------+-------+
| NrStudenta | Imie
| Nazwisko
| Uwagi | Grupa |
+------------+----------+--------------+-------+-------+
| 1
| Mariusz | Lewandowski | xxxx | xy
|
| 2
| Jakub
| Stefanowski |
| xy
|
| 3
| Marek
| Giebułtowski |
| xy
|
| 4
| Barbara | Jeziorek
|
| xy
|
| 6
| Wojciech | Wachal
˛
|
| xy
|
| 72
| Jakub
| Janoszek
|
| xy
|
| 73
| Maciej
| Gowin
|
| xy
|
| 74
| Tadeusz | Drozda
|
| xy
|
| 75
| Marek
| Kolejny
|
| xy
|
+------------+----------+--------------+-------+-------+
9 rows in set (0.03 sec)
c 2010-11 P. F. Góra
Copyright 4–46
Zmienne tymczasowe
SQL pozwala na definiowanie zmiennych tymczasowych — nazwa zmiennej
tymczasowej zawsze zaczyna sie˛ od @. Zmienna istnieje dopóty, dopóki nie zostanie zakończone połaczenie
˛
z serwerem. Procesy klienckie nie widza˛ zmiennych zdefiniowanych przez inne procesy.
mysql> SET @a=5;
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT @a-2;
+------+
| @a-2 |
+------+
| 3
|
+------+
1 row in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–47
Zmiennej można przypisać wartość, która jest wynikiem zapytania:
mysql> SET @b=(SELECT NrStudenta FROM Studenci2 WHERE Imie=’Tadeusz’);
Query OK, 0 rows affected (0.89 sec)
mysql> SELECT @b, @a+@b;
+------+-------+
| @b
| @a+@b |
+------+-------+
| 74
| 79
|
+------+-------+
1 row in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–48
Aliasy
W zapytaniu SELECT możemy nadawać kolumnom inne nazwy niż te, które wystepuj
˛ a˛ w definicji tabeli. Nosza˛ one nazwe˛ aliasów.
mysql> SELECT NrStudenta AS ToJestNumer, Imie FROM Studenci2;
+-------------+----------+
| ToJestNumer | Imie
|
+-------------+----------+
| 1
| Mariusz |
| 2
| Jakub
|
| 3
| Marek
|
| 4
| Barbara |
| 6
| Wojciech |
| 72
| Jakub
|
| 73
| Maciej
|
| 74
| Tadeusz |
| 75
| Marek
|
| 65536
| X
|
+-------------+----------+
10 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–49
Niekiedy wygodnie jest użyć aliasu w dalszej cz˛eści zapytania, ale nie można go
użyć w kaluzuli WHERE
mysql> SELECT NrStudenta AS ToJestNumer, Imie FROM Studenci2
-> WHERE ToJestNumer > 10;
ERROR 1054 (42S22): Unknown column ’ToJestNumer’ in ’where clause’
Można natomiast użyć aliasu w klauzuli HAVING:
mysql> SELECT NrStudenta AS ToJestNumer, Imie as ’Pierwsze imi˛
e’ FROM Studenci2
-> HAVING ToJestNumer > 10;
+-------------+---------------+
| ToJestNumer | Pierwsze imi˛
e |
+-------------+---------------+
| 72
| Jakub
|
| 73
| Maciej
|
| 74
| Tadeusz
|
| 75
| Marek
|
| 65536
| X
|
+-------------+---------------+
5 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–50
Jest to szczególnie przydatne, gdy w warunku wystepuje
˛
wartość obliczana na
podstawie wiecej
˛
niż jednej kolumny:
mysql> SELECT CONCAT(Imie,’ ’,Nazwisko) AS Imie_Nazwisko FROM Studenci2
-> HAVING Imie_Nazwisko LIKE "%r%z%";
+---------------------+
| Imie_Nazwisko
|
+---------------------+
| Mariusz Lewandowski |
| Barbara Jeziorek
|
| Tadeusz Drozda
|
+---------------------+
3 rows in set (0.00 sec)
c 2010-11 P. F. Góra
Copyright 4–51
Download