Widoki (views) - Perspektywy: Perspektywa – dynamicznie obliczany wynik jednej lub wielu operacji relacyjnych tworzących nową relację (tabelę) z relacji bazowych. Perspektywa jest relacją wirtualną, która nie musi fizycznie istnieć w bazie danych, ale może być wyliczona w każdej chwili na żądanie użytkownika. Składnia polecenia: CREATE [OR REPLACE] VIEW nazwa_perspektywy [(lista_kolumn)] AS SELECT zapytanie [WITH [CASCADED | LOCAL] CHECK OPTION]
Jeżeli w poleceniu pominięta jest lista kolumn, to każda z kolumn perspektywy będzie miała taką samą nazwę, jak odpowiednia kolumna w wyniku zapytania SELECT. Lista kolumn powinna być podana, jeśli istnieją jakiekolwiek niejasności dotyczące nazw kolumn (np. dla kolumn wyliczanych lub, gdy w wyniku złączenia powstają dwie kolumny o identycznych nazwach).
Usuwanie perspektywy: DROP VIEW [IF EXISTS] nazwa_perspektywy [, nazwa_perspektywy] ... [RESTRICT | CASCADE] Modyfikowanie perspektywy: ALTER VIEW nazwa_perspektywy [(lista_kolumn)] AS SELECT zapytanie [WITH [CASCADED | LOCAL] CHECK OPTION]
Rodzaje perspektyw: Utworzenie perspektywy poziomej: mysql> CREATE VIEW _11_biuro_B003 AS SELECT personelnr, imie, nazwisko, stanowisko, pensja FROM personel WHERE biuronr='B003'; mysql> SELECT * FROM _11_biuro_B003; +------------+-------------+------------+------------+--------+ | personelnr | imie | nazwisko | stanowisko | pensja | | SB20 | Sabina | Bober | dyrektor | 2400 | | SB21 | Daniel | Frankowski | kierownik | 1800 | | SB22 | Małgorzata | Kowalska | asystent | 1000 | | SB23 | Anna | Biały | asystent | 1200 |
Utworzenie perspektywy pionowej: mysql> CREATE VIEW _10_dyrektorzy AS SELECT personelnr, pensja FROM personel WHERE stanowisko='dyrektor'; mysql> SELECT * FROM _10_dyrektorzy; +------------+--------+ | personelnr | pensja | | SB20 | 2400 | | SB30 | 2500 | | SG20 | 2200 | | SL30 | 3000 |
Perspektywy oparte na grupowaniu: mysql> CREATE VIEW srednie AS SELECT uczen, przedmiot, AVG(ocena) AS srednia FROM oceny GROUP BY uczen, przedmiot; mysql> SELECT* FROM srednie; +-------+------------+---------+ | uczen | przedmiot | srednia | | 1 | biologia | 5.00000 | | 1 | matematyka | 3.83333 | | 1 | polski | 4.00000 | | 2 | biologia | 3.25000 | | 2 | matematyka | 3.12500 | | 2 | polski | 4.66667 |
Podaj nieruchomości, które były wynajmowane częściej niż średnio Pierwszy etap: Policz ile razy była wynajmowana każda nieruchomość: mysql> CREATE VIEW ilosc AS SELECT count(*) AS ile FROM wynajecie GROUP BY nieruchomoscnr; mysql> SELECT * FROM ilosc; +-----+ | ile | | 3 | | 4 | | 2 |
Wyświetl, które nieruchomości były wynajmowane częściej niż średnio: Drugi etap: Wyświetl, które nieruchomości były wynajmowane częściej niż średnio: mysql> CREATE VIEW srednio AS SELECT n.nieruchomoscnr, miasto, n.czynsz, count(*) FROM nieruchomosc n, wynajecie w WHERE w.nieruchomoscnr = n.nieruchomoscnr GROUP BY nieruchomoscnr HAVING count(*)>=(SELECT AVG(ile) FROM ilosc); mysql> SELECT * FROM srednio; +----------------+-----------+--------+----------+ | nieruchomoscNr | miasto | czynsz | count(*) | | A14 | Augustów | 715 | 3 | | B16 | Białystok | 495 | 4 |
Wartość średnia wyniosła: SELECT AVG(ile) AS srednia FROM ilosc; mysql> SELECT AVG(ile) AS srednia FROM ilosc; +---------+ | srednia | | 2.2857 |
Zadanie bez stosowania perspektyw: SELECT n.nieruchomoscnr, miasto, n.czynsz, count(*) FROM nieruchomosc n, wynajecie w WHERE w.nieruchomoscnr = n.nieruchomoscnr GROUP BY nieruchomoscnr HAVING count(*)>=(SELECT AVG(ile) FROM (SELECT count(*) AS ile FROM wynajecie w GROUP BY nieruchomoscnr) tmp); +----------------+-----------+--------+----------+ | nieruchomoscNr | miasto | czynsz | count(*) | | A14 | Augustów | 715 | 3 | | B16 | Białystok | 495 | 4 |
Bez warunku WHERE Wszystkie 7 nieruchomości i wszystkie 17 wynajęć mysql> SELECT n.nieruchomoscnr, miasto, n.czynsz, count(*) FROM nieruchomosc n, wynajecie w GROUP BY nieruchomoscnr HAVING count(*)>=(SELECT AVG(ile) FROM (SELECT count(*) AS ile FROM wynajecie GROUP BY nieruchomoscnr) tmp); +----------------+-----------+--------+----------+ | nieruchomoscNr | miasto | czynsz | count(*) | | A14 | Augustów | 715 | 17 | | B16 | Białystok | 495 | 17 | | B17 | Białystok | 412 | 17 | | B18 | Białystok | 385 | 17 | | B21 | Białystok | 660 | 17 | | G01 | Grajewo | 830 | 17 | | L94 | Łomża | 440 | 17 | Wszystkie 7 nieruchomości i wszystkie 17 wynajęć
Przykłady: mysql> CREATE TABLE test (ilosc INT, cena INT); mysql> INSERT INTO test VALUES(3, 50); mysql> CREATE VIEW w AS SELECT ilosc, cena, ilosc*cena AS wartosc FROM test; mysql> SELECT * FROM w; +-------+------+---------+ | ilosc | cena | wartosc | | 3 | 50 | 150 |
mysql> CREATE VIEW roczna AS SELECT personelNr, stanowisko, pensja, pensja*12 AS pensja_roczna FROM personel; mysql> SELECT * FROM roczna; +------------+------------+--------+---------------+ | personelNr | stanowisko | pensja | pensja_roczna | | SE20 | dyrektor | 14050 | 168600 | | SE21 | kierownik | 1500 | 18000 | | SE22 | asystent | 1366 | 16392 | | SE23 | asystent | 11566 | 138792 | | SF10 | dyrektor | 16250 | 195000 | | SL20 | kierownik | 1200 | 14400 | | SL21 | asystent | 11366 | 136392 | | SL22 | asystent | 1466 | 17592 | | SL30 | dyrektor | 14650 | 175800 | | SL31 | asystent | 11266 | 135192 | | SL32 | kierownik | 13266 | 159192 |
Przykłady wprowadzania danych przez widoki: mysql> CREATE TABLE t1 (a INT); mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2 WITH CHECK OPTION; mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0 WITH LOCAL CHECK OPTION; mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0 WITH CASCADED CHECK OPTION; mysql> INSERT INTO v1 VALUES (2); ERROR 1369 (HY000): CHECK OPTION failed 'biuro.v1' mysql> INSERT INTO v2 VALUES (2); mysql> select * from t1; +------+ | a | | 2 |
mysql> INSERT INTO v3 VALUES (2); ERROR 1369 (HY000): CHECK OPTION failed 'biuro.v3‘ mysql> INSERT INTO v1 VALUES (1); mysql> select * from t1; +------+ | a | | 2 | | 1 | mysql> select * from v1; /* podobnie v2, v3) */
Przykłady wprowadzania danych w bazie biuro: mysql> CREATE VIEW _10_dyrektorzy AS SELECT personelnr, nazwisko, imie, stanowisko, pensja,biuroNr FROM personel WHERE stanowisko='dyrektor' AND pensja >= 2500 WITH CHECK OPTION; mysql> SELECT * FROM _10_dyrektorzy2; +-----------+------------+-----------+-----------+--------+---------+ | personelnr| nazwisko | imie | stanowisko| pensja | biuroNr | | SB30 | Michalska | Katarzyna | dyrektor | 2500 | B006 | | SL30 | Wiśniewski | Jan | dyrektor | 14650 | B005 | mysql> INSERT INTO _10_dyrektorzy (personelNr, nazwisko, imie, stanowisko,pensja, biuroNr) VALUES ('SA10', 'Biedak', 'Jan', 'dyrektor', 2000,'B007'); ERROR 1369 (HY000): CHECK OPTION failed 'biuro._10_dyrektorzy'
mysql> SELECT * FROM _10_dyrektorzy; mysql> INSERT INTO _10_dyrektorzy (personelNr, nazwisko, imie, stanowisko, pensja, biuroNr) VALUES ('SF10','Bogacz','Jan', 'dyrektor', 5000, 'B001'); mysql> SELECT * FROM _10_dyrektorzy; +-----------+------------+-----------+-----------+--------+---------+ | personelnr| nazwisko | imie | stanowisko| pensja | biuroNr | | SB30 | Michalska | Katarzyna | dyrektor | 2500 | B006 | | SF10 | Bogacz | Jan | dyrektor | 5000 | B001 | | SL30 | Wiśniewski | Jan | dyrektor | 14650 | B005 |