Przyklady polecen SELECT SQL


PRZYKŁADY ZAPYTAŃ W JĘZYKU SQL

Opracował: Piotr Parewicz Instytut Informatyki PW

Materiał dydaktyczny przeznaczony dla studentów kursów

BAZY DANYCH i WPROWADZENIE DO BAZ DANYCH

SCHEMAT BAZY DANYCH DO PRZYKŁADÓW ZAPYTAŃ

KLIENCI

Id_klienta

Nazwa_firmy

Adres

Miasto

Nr_tel

Nr_faksu

ZAMÓWIENIA

Nr_zam

Data_zam

Id_klienta

Wartość_zam

POZYCJE_ZAMÓWIEŃ

Nr_zam

Nr_towaru

Ilość_zam

TOWARY

Nr_towaru

Rodzaj_towaru

Nazwa_producenta

Model

Cena_sprzed

Ilość_w_mag

DOSTAWCY

Id_dostawcy

Nazwa_firmy

Adres

Miasto

Kraj

OFERTY_DOSTAWCÓW

Id_dostawcy

Nr_towaru

Cena

DOSTAWY

Nr_dostawy

Id_dostawcy

Data_zam

Data_przyjęcia

Nr_towaru

Ilość

PRZYKŁADY ZAPYTAŃ (POLECEŃ) W JĘZYKU SQL

CZĘŚĆ 1 - DOSTĘP DO DANYCH Z JEDNEJ TABELI

Wybór wierszy spełniających zadany warunek i kolumn wskazanych nazwą

1.1 Podać wykaz klientów z Krakowa: dla każdego klienta podać jego identyfikator oraz nazwę firmy.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE Miasto = `Kraków' ;

1.2 Podać wykaz wszystkich modeli namiotów. Dla każdego modelu podać numer katalogowy, nazwę producenta i oznaczenie modelu.

SELECT Nr_towaru, Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru = 'Namiot' ;

1.3 Podać wykaz zamówień złożonych przez klienta o identyfikatorze 1123. Dla każdego zamówienia podać numer zamówienia, datę i wartość zamówienia

SELECT Nr_zam, Data_zam, Wartość_zam

FROM Zamówienie

WHERE Id_klienta = 1123 ;

1.4 Podać nazwę firmy i miasto dla klienta o identyfikatorze 2575.

SELECT Nazwa_firmy, Miasto

FROM Klienci

WHERE Id_klienta = 2575 ;

To polecenie zwraca tabelę jednowierszową-przewidywanie takie wynika z faktu, że kolumna Id_klienta jest kluczem

1.5 Podać wykaz dostawców z Austrii. Podać pełne dane każdego dostawcy.

SELECT *

FROM Dostawcy

WHERE Kraj = `Austria' ;

Symbol * zastępuje listę wszystkich kolumn

1.6 Podać wykaz wszystkich klientów: dla każdego klienta podać identyfikator nazwę firmy i kraj.

SELECT Id_klienta, Nazwa_firmy, Kraj

FROM Klienci ;

Brak warunku wyboru wierszy - polecenie zwraca wszystkie wiersze tabeli

1.7 Podać pełne dane dla wszystkich klientów

SELECT *

FROM Klienci ;

Polecenie zwraca całą tabelę

1.8 Podać wykaz zamówień o wartości przekraczającej 20 000 złotych. Dla każdego takiego zamówienia podać jego numer, identyfikator klienta i wartość zamówienia.

SELECT Nr_zam, Id_klienta, Wartość_zam

FROM Zamówienia

WHERE Wartość_zam > 20000 ;

1.9 Podać wykaz dostawców zagranicznych. Dla każdego dostawcy podać nazwę firmy, miasto i kraj.

SELECT Nazwa_firmy, Miasto, Kraj

FROM Dostawcy

WHERE Kraj <> 'Polska' ;

1.10 Podać wykaz wszystkich zamówień złożonych między 15/04/2004 a 30/04/2004. Dla każdego zamówienia podać numer, datę i wartość.

SELECT Nr_zam, Data_zam, Wartość_zam

FROM Zamówienie

WHERE Data_zam BETWEEN '15/04/2004' AND '30/04/2004';

Użycie słowa kluczowego DISTINCT

1.11 Podać wykaz krajów i miast, w których mieszczą się firmy dostawców.

SELECT DISTINCT Miasto, Kraj

FROM Dostawcy ;

Przykłady złożonych warunków wyboru wierszy

1.12 Podać wykaz modeli plecaków produkcji firmy PRS. Dla każdego modelu podać numer katalogowy, oznaczenie modelu i cenę.

SELECT Nr_towaru, Model, Cena_sprzed

FROM Towary

WHERE Rodzaj_towaru = 'Plecak' AND Nazwa_producenta = 'PRS' ;

1.13 Podać wykaz wszystkich artykułów produkcji firm TWX i XYZ. Dla każdego artykułu podać rodzaj, nazwę producenta i oznaczenie modelu.

SELECT Rodzaj_towaru, Nazwa_producenta, Model

FROM Towary

WHERE Nazwa_producenta = 'TWX' OR Nazwa_producenta = 'XYZ' ;

1.14 Podać wykaz wszystkich modeli śpiworów o cenach mieszczących się w granicach od 100 do 400 złotych. Dla każdego modelu podać numer katalogowy, nazwę producenta, oznaczenie modelu i cenę.

SELECT Nr_towaru, Nazwa_producenta, Model, Cena_sprzed

FROM Towary

WHERE Rodzaj_towaru = 'Śpiwór' AND Cena_sprzed BETWEEN 100 AND 400 ;

1.15 Podać wykaz wszystkich zamówień o wartości przekraczającej 50 000 złotych, złożonych między 15/04/2004 a 30/04/2004. Dla każdego zamówienia podać numer, datę i wartość.

SELECT Nr_zam, Data_zam, Wartość_zam

FROM Zamówienie

WHERE Data_zam BETWEEN '15-APR-2004' AND '30-APR-2004' AND Wartość_zam > 50000;

1.16 Dla każdego modelu namiotu produkcji firmy UWZ lub QRT lub XYZ, którego zapas w magazynie jest mniejszy niż 100 sztuk, podać numer katalogowy, markę i oznaczenie modelu.

SELECT Nr_towaru, Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru =

'Namiot'

AND(Nazwa_producenta = 'UWZ'

OR Nazwa_producenta = 'QRT'

OR Nazwa_producenta = 'XYZ'

)

AND Ilość_w_mag < 100 ;

Użycie operatora IN

1.17 Polecenie z zad. 1.16 można zapisać w następującej postaci, korzystając z operatora IN:

SELECT Nr_towaru, Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru = 'Namiot'

AND Nazwa_producenta IN ('UWZ', 'QRT', 'XYZ')

AND Ilość_w_mag < 100 ;

Użycie operatora LIKE

1.18 Podać wykaz modeli śpiworów o oznaczeniu rozpoczynającym się od słowa “Borsuk”. Dla każdego modelu podać numer katalogowy i nazwę modelu.

SELECT Nr_towaru, Model

FROM Towary

WHERE Rodzaj_towaru = 'Śpiwór' AND Model LIKE `Borsuk%' ;

Przykłady wyrażeń w sekcji WHERE

1.19 Podać wykaz modeli plecaków, takich że wartość zapasów danego modelu przekracza 20 000 złotych. Dla każdego modelu podać numer katalogowy, nazwę producenta i nazwę modelu.

SELECT Nr_towaru, Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru = 'Plecak'

AND Ilość_w_mag * Cena_sprzed > 20000 ;

1.20 Podać wykaz dostaw przyjętych w okresie od 15/04/2004 do 30/04/2004, dla których czas oczekiwania przekroczył 20 dni. Dla każdej dostawy podać numer dostawy i identyfikator dostawcy.

SELECT Nr_dostawy, Id_dostawcy

FROM Dostawy

WHERE Data_przyjęcia BETWEEN '15/04/2004' AND '30/04/2004'

AND Data_przyjęcia - Data_zam > 20 ;

1.21 Podać wykaz dostaw sprzed 2 miesięcy lub wcześniejszych. Dla każdej dostawy podać numer dostawy, identyfikator dostawcy, numer katalogowy towaru i datę przyjęcia

SELECT Nr_dostawy, Id_dostawcy, Nr_towaru, Data_przyjęcia

FROM Dostawy

WHERE Months_between (Sysdate - Data_przyjęcia) > 2 ;

Użyto funkcji wbudowanych Sysdate oraz Months_between

1.22 Podać wykaz zamówień złożonych w pażdzierniku 2003,o wartości przekraczającej 20 000 złotych. Dla każdego takiego zamówienia podać jego numer, identyfikator klienta i wartość zamówienia.

SELECT Nr_zam, Id_klienta, Wartość_zam

FROM Zamówienia

WHERE Wartość_zam > 20000 AND Trunc (Data_zam, `MM') = `01/10/2003' ;

Użyto funkcji wbudowanej Trunc

Uporządkowanie wierszy wyniku za pomocą specyfikacji ORDER BY

1.23 Podać wykaz klientów z Poznania. Dla każdego klienta podać identyfikator, nazwę firmy i adres. Uporządkować alfabetycznie wg nazwy firmy.

SELECT Id_klienta, Nazwa_firmy, Adres

FROM Klienci

WHERE Miasto = `Poznań' ;

ORDER BY Nazwa_firmy ;

1.24 Podać wykaz wszystkich zamówień od klienta o identyfikatorze 1123, złożonych w okresie od 01/12/2003. Dla każdego zamówienia podać numer zamówienia, datę i wartość. Uporządkować wg wartości od największej do najmniejszej.

SELECT Nr_zam, Data_zam, Wartość_zam

FROM Zamówienie

WHERE Id_klienta = 1123 AND Data_zam >= `01/12/2003' ;

ORDER BY Wartość_zam DESC ;

1.25 Podać wykaz wszystkich dostawców. Dla każdego dostawcy podać nazwę firmy, miasto i kraj. Uporządkować alfabetycznie według krajów, a w ramach kraju - wg miast.

SELECT Nazwa_firmy, Miasto, Kraj

FROM Dostawcy

ORDER BY Kraj, Miasto ;

Dołączanie kolumn z wartościami wyliczanymi

1.26 Podać wykaz modeli namiotów produkcji firmy XYZ z ceną aktualną i ceną obniżoną o 20%.

SELECT Nr_towaru, Model, Cena_sprzed, Cena_sprzed * 0.8

FROM Towary

WHERE Rodzaj_towaru = 'Namiot'

AND Nazwa_producenta = 'XYZ' ;

1.27 Podać wykaz dostaw przyjętych w okresie od 15/04/2004 do 30/04/2004, dla których czas oczekiwania przekroczył 20 dni. Dla każdej dostawy podać numer dostawy, identyfikator dostawcy i czas oczekiwania.

SELECT Nr_dostawy, Id_dostawcy, Data_przyjęcia - Data_zam

FROM Dostawy

WHERE Data_przyjęcia BETWEEN '15/04/2004' AND '30/04/2004'

AND Data_przyjęcia - Data_zam > 20 ;

1.28 Podać wykaz wartości zapasów dla poszczególnych modeli namiotów.

SELECT Nr_towaru, Model, Cena_sprzed * Ilość_w_mag

FROM Towary

WHERE Rodzaj_towaru = 'Namiot' ;

Wybranie wierszy, w których wartość we wskazanej kolumnie jest określona/nieokreślona

1.29 Podać wykaz klientów (identyfikator, nazwa firmy), którzy nie mają faksu.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE Nr_faksu IS NULL ;

1.30 Podać wykaz dostaw (numer dostawy, identyfikator dostawcy, czas oczekiwania) zamówionych nie wcześniej niż przed 7 dniami, które już zostały odebrane (data przyjęcia jest określona).

SELECT Nr_dostawy, Id_dostawcy, Data_przyjęcia - Data_zam

FROM Dostawy

WHERE Sysdate - Data_zam < 7 AND Data_przyjęcia IS NOT NULL ;

CZĘŚĆ 2 - DOSTĘP DO DANYCH Z DWÓCH LUB WIĘCEJ TABEL

Złączenie dwóch tabel

W zadaniach 2.1, 2.2 wiersze tabeli wynikowej powstają z par wierszy spełniających warunek złączenia

2.1 Podać wykaz wszystkich zarejestrowanych zamówień. dla każdego zamówienia podać: numer i datę zamówienia oraz nazwę firmy zamawiającej i miasto, w którym ta firma się znajduje.

a) Postać zapytania z wyrażeniem złączeniowym w sekcji FROM:

SELECT Zamówienia.Nr_zam, Zamówienia.Data_zam, Klienci.Nazwa_firmy, Klienci.Miasto

FROM Zamówienia

JOIN Klienci ON Zamówienia.Id_klienta = Klienci.Id_klienta ;

b) Postać zapytania z warunkiem złączenia w sekcji WHERE:

SELECT Zamówienia.Nr_zam, Zamówienia.Data_zam, Klienci.Nazwa_firmy, Klienci.Miasto

FROM Zamówienia, Klienci

WHERE Zamówienia.Id_klienta = Klienci.Id_klienta ;

c) Postać zapytania odwołująca się do operacji złączenia naturalnego - domyślnym warunkiem złączenia jest równość wartości w kolumnach o tej samej nazwie:

SELECT Zamówienia.Nr_zam, Zamówienia.Data_zam, Klienci.Nazwa_firmy, Klienci.Miasto

FROM Zamówienia NATURAL

JOIN Klienci ;

d) Postać zapytania odwołująca się do operacji JOIN USING - domyślnym warunkiem złączenia jest równość wartości w kolumnach o podanej nazwie, tej samej w obu tabelach:

SELECT Zamówienia.Nr_zam, Zamówienia.Data_zam, Klienci.Nazwa_firmy, Klienci.Miasto

FROM Zamówienia

JOIN Klienci USING Id_klienta ;

2.2 Podać wykaz wszystkich zarejestrowanych dostaw. Dla każdej dostawy podać numer katalogowy towaru, zamówioną ilość towaru i nazwę firmy dostawcy.

a)

SELECT Dostawy.Nr_towaru, Dostawy.Ilość_zam, Dostawcy.Nazwa_firmy

FROM Dostawy JOIN Dostawcy ON Dostawy.Id_dostawcy = Dostawcy.Id_dostawcy

b)

SELECT Dostawy.Nr_towaru, Dostawy.Ilość_zam, Dostawca.Nazwa_firmy

FROM Dostawy, Dostawcy

WHERE Dostawy.Id_dostawcy = Dostawcy.Id_dostawcy ;

c)

SELECT Dostawy.Nr_towaru, Dostawy.Ilość_zam, Dostawcy.Nazwa_firmy

FROM Dostawy NATURAL JOIN Dostawcy ;

d)

SELECT Dostawy.Nr_towaru, Dostawy.Ilość_zam, Dostawcy.Nazwa_firmy

FROM Dostawy JOIN Dostawcy USING Id_dostawcy ;

Złączenie dwóch tabel z dodatkową selekcją

W zadaniach 2.3-2.8 wiersze tabeli wynikowej powstają z par wierszy spełniających warunek złączenia i dodatkowe warunki selekcji nałożone na wartości w kolumnach innych niż kolumny uczestniczące w warunku złączenia.

2.3 Podać wykaz zamówień o wartości przekraczającej 30 000 złotych. Dla każdego takiego zamówienia podać identyfikator klienta, nazwę firmy, numer zamówienia i wartość zamówienia.

Dodatkowy warunek selekcji jest nałożony na wiersze z jednej tabeli

a)

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, Zamówienia.Nr_zam, Zamówienia.Wartość_zam

FROM Klienci JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Zamówienia.Wartość_zam > 30000 ;

W postaci z wyrażeniem złączeniowym sekcja WHERE zawiera tylko dodatkowy warunek selekcji

b)

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, Zamówienia.Nr_zam,

Zamówienia.Wartość_zam

FROM Klienci, Zamówienia

WHERE Klienci.Id_klienta =

Zamówienia.Id_klienta AND Zamówienia.Wartość_zam > 30000 ;

W tej postaci zapytania zarówno warunek złączenia, jak i dodatkowy warunek selekcji są zawarte w sekcji WHERE

c)

SELECT Id_klienta, Klienci.Nazwa_firmy, Zamówienia.Nr_zam, Zamówienia.Wartość_zam

FROM Klienci NATURAL JOIN Zamówienia

WHERE Zamówienia.Wartość_zam > 30000 ;

d)

SELECT Id_klienta, Klienci.Nazwa_firmy, Zamówienia.Nr_zam, Zamówienia.Wartość_zam

FROM Klienci JOIN Zamówienia USING Id_klienta

WHERE Zamówienia.Wartość_zam > 30000 ;

W postaciach zapytania odwołujących się do domyślnego warunku złączenia (operacje NATURAL JOIN, JOIN USING) sekcja WHERE oczywiście zawiera tylko dodatkowy warunek selekcji.

W następnych przykładach będzie podawana tylko jedna lub dwie spośród możliwych postaci zapisu złączenia.

2.4 Podać wykaz dostaw przyjętych w okresie od 15/04/2004 do 30/04/2004. Dla każdej dostawy podać identyfikator dostawcy, datę przyjęcia dostawy, numer katalogowy towaru, nazwę producenta, oznaczenie modelu i liczbę sztuk w dostawie.

Podobnie jak w poprzednim zadaniu dodatkowy warunek selekcji jest nałożony na wiersze z jednej tabeli

a)

SELECT Dostawy.Id_dostawcy, Dostawy.Data_przyjęcia, Towary.Nr_towaru,

Towary.Nazwa_producenta, Towary.Model, Dostawy.Ilość_zam

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Dostawy.Data_przyjęcia BETWEEN '15/04/2004' AND '30/04/2004' ;

b)

SELECT Dostawy.Id_dostawcy, Dostawy.Data_przyjęcia, Towary.Nr_towaru,

Towary.Nazwa_producenta, Towary.Model, Dostawy.Ilość_zam

FROM Dostawy, Towary

WHERE Dostawy.Nr_towaru = Towary.Nr_towaru

AND Dostawy.Data_przyjęcia BETWEEN '15/04/2004' AND '30/04/2004';

2.5 Podać wykaz zamówień o wartości przekraczającej 30 000 złotych, złożonych przez klientów z Krakowa. Dla każdego takiego zamówienia podać identyfikator klienta, nazwę firmy, numer zamówienia i wartość zamówienia.

W tym zadaniu są nałożone dodatkowe warunki selekcji na wiersze z obu tabel

a)

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, Zamówienia.Nr_zam,

Zamówienia.Wartość_zam

FROM Klienci, Zamówienia

WHERE Klienci.Id_klienta = Zamówienia.Id_klienta

AND Klienci.Miasto = 'Kraków'

AND Zamówienia.Wartość_zam > 30000 ;

b)

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, Zamówienia.Nr_zam,

Zamówienia.Wartość_zam

FROM Klienci JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Klienci.Miasto = 'Kraków'

AND Zamówienia.Wartość_zam > 30000 ;

2.6 Podać wykaz dostaw namiotów przyjętych po 15/04/2004. Dla każdej dostawy podać identyfikator dostawcy, datę przyjęcia dostawy, numer katalogowy, nazwę producenta i oznaczenie modelu namiotu i liczbę sztuk w dostawie.

Podobnie jak w poprzednim zadaniu, dodatkowe warunki selekcji są nałożone na wiersze z obu tabel

a)

SELECT Dostawy.Id_dostawcy, Dostawy.Data_przyjęcia, Towary.Nr_towaru,

Towary.Nazwa_producenta, Towary.Model, Dostawy.Ilość_zam

FROM Dostawy, Towary

WHERE Dostawy.Nr_towaru = Towary.Nr_towaru

AND Dostawy.Data_przyjęcia > `15/04/2004'

AND Towary.Rodzaj_towaru = 'Namiot' ;

b)

SELECT Dostawy.Id_dostawcy, Dostawy.Data_przyjęcia, Towary.Nr_towaru,

Towary.Nazwa_producenta, Towary.Model, Dostawy.Ilość_zam

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Dostawy.Data_przyjęcia > `15/04/2004'

AND Towary.Rodzaj_towaru = 'Namiot' ;

2.7 Podać wykaz zamówień (numer zamówienia i wartość) złożonych przez klientów z Gdańska w okresie od 15/04/2004 do 30/04/2004.

Tabela wynikowa ma zawierać dane, które pochodzą tylko z tabeli ZAMÓWIENIA. Jest jednak konieczne złączenie z tabelą KLIENCI, aby wybrać te wiersze tabeli ZAMÓWIENIA, dla których odpowiadające im wiersze w tabeli KLIENCI zawierają żądaną wartość w kolumnie MIASTO.

SELECT Zamówienia.Nr_zam, Zamówienia.Wartość_zam

FROM Klienci JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Zamówienia.Data_zam BETWEEN '15/04/2004' AND '30/04/2004'

AND Klienci.Miasto = 'Gdańsk' ;

2.8 Podać wykaz artykułów oferowanych przez dostawcę o numerze identyfikacyjnym 235.

Analogicznie jak w poprzednim zadaniu tabela wynikowa ma zawierać dane, które pochodzą z jednej tylko tabeli. Złączenie jest konieczne, aby wybrać wiersze według warunku odwołującego się do danych z odpowiednich wierszy drugiej tabeli.

SELECT Towary.Rodzaj_towaru, Towary.Nazwa_producenta, Towary.Model

FROM Towary JOIN Oferty_dostawców

ON Towary.Nr_towaru = Oferty_dostawców.Nr_towaru

WHERE Oferty_dostawców.Id_dostawcy = 235 ;

Złączenie trzech lub więcej tabel

2.9 Podać pełny wykaz wszystkich zarejestrowanych ofert dostawców. Dla każdej oferty podać nazwę firmy dostawcy, rodzaj towaru, nazwę producenta, oznaczenie modelu i oferowaną cenę.

a)

SELECT Dostawcy.Nazwa_firmy, Towary.Rodzaj_towaru,

Towary.Nazwa_producenta, Towary.Model, Oferty_dostawców.Cena

FROM Towary, Oferty_dostawców, Dostawcy

WHERE Towary.Nr_towaru = Oferty_dostawców.Nr_towaru

AND Oferty_dostawców.Id_dostawcy = Dostawcy.Id_dostawcy ;

b)

SELECT Dostawcy.Nazwa_firmy, Towary.Rodzaj_towaru, Towary.Nazwa_producenta, Towary.Model, Oferty_dostawców.Cena

FROM (Towary JOIN Oferty_dostawców

ON Towary.Nr_towaru =

Oferty_dostawców.Nr_towaru)

JOIN Dostawcy ON Oferty_dostawców.Id_dostawcy = Dostawcy.Id_dostawcy ;

2.10 Podać wykaz dostaw butów turystycznych zamówionych u dostawców mających siedzibę w Austrii. Dla każdej dostawy podać nazwę firmy dostawcy, nazwę producenta, oznaczenie modelu i zamówioną liczbę par.

SELECT Dostawcy.Nazwa_firmy, Towary.Nazwa_producenta, Towary.Model, Dostawy.Ilość_zam

FROM Towary, Dostawy, Dostawcy

WHERE Towary.Nr_towaru = Dostawy.Nr_towaru

AND Dostawy.Id_dostawcy = Dostawcy.Id_dostawcy

AND Towary.Rodzaj_towaru = 'Buty turystyczne'

AND Dostawcy.Kraj = 'Austria' ;

SELECT Dostawca.Nazwa_firmy, Towary.Nazwa_producenta, Towary.Model, Dostawy.Ilość_zam

FROM (Towary JOIN Dostawy

ON Towary.Nr_towaru = Dostawy.Nr_towaru)

JOIN Dostawcy ON Dostawy.Id_dostawcy = Dostawcy.Id_dostawcy

WHERE Towary.Rodzaj_towaru = 'Plecak'

AND Dostawcy.Kraj = 'Austria' ;

2.11 Podać wykaz modeli namiotów (nazwa producenta, model), dla których są oferty od dostawców z Niemiec.

SELECT Towary.Nazwa_producenta, Towary.Model

FROM Towary, Oferty_dostawców, Dostawcy

WHERE Towary.Nr_towaru = Oferty_dostawców.Nr_towaru

AND Oferty_dostawców.Id_dostawcy = Dostawcy.Id_dostawcy

AND Towary.Rodzaj_towaru = 'Namiot'

AND Dostawcy.Kraj = 'Niemcy' ;

2.12

Podać wykaz pozycji zamówień złożonych po 15/04/2004, w których zamawianym towarem są namioty, a ilość zamawiana wynosi nie mniej niż 100 sztuk. Dla każdej takiej pozycji podać nazwę firmy zamawiającej, numer zamówienia, zamówioną liczbę sztuk i wartość tej pozycji zamówienia.

SELECT Klienci.Nazwa_firmy, Zamówienia.Nr_zam, Pozycje_zamówień.Ilość_zam,

Pozycje_zamówień.Ilość_zam * Towary.Cena_sprzed

AS Wartość_pozycji

FROM Klienci, Zamówienia, Pozycje_zamówień, Towary

WHERE Klienci.Id_klienta = Zamówienia.Id_klienta

AND Zamówienia.Nr_zam = Pozycje_zamówień.Nr_zam

AND Zamówienia.Data_zam > 15/04/2004

AND Pozycje_zamówień.Nr_towaru = Towary.Nr_towaru

AND Towary.Rodzaj_towaru = `Namiot'

AND Pozycje_zamówień.Ilość_zam >= 100 ;

Złączenie w ramach jednej tabeli

2.13 Zapytanie odwołuje się do tabeli o następującej strukturze:
PRACOWNICY

Id_pracownika

Nazwisko

Imię

Stanowisko

Id_przełożonego

Kolumna Id_przełożonego jest kluczem obcym odwołującym się do klucza tej samej tabeli.
Podać listę pracowników - dla każdego pracownika podać jego identyfikator, nazwisko i imię oraz nazwisko i imię przełożonego.

SELECT P1.Id_pracownika, , P1.Nazwisko, P1.Imię,

P2.Nazwisko AS Nazwisko_przełożonego, P2.Imię AS Imię_przełożonego

FROM Pracownicy P1, Pracownicy P2

WHERE P1.Id_przełożonego = P2.Id_pracownika ;

To złączenie można wyobrażać sobie jako złączenie dwóch egzemplarzy jednej tabeli. Aby w odwołaniach rozróżniać te dwa pojęciowe egzemplarze tabeli Pracownicy, trzeba wprowadzić dwa różne synonimy dla nazwy tabeli. Natomiast synonimy nazw kolumn są wprowadzone tylko dla poprawienia czytelności wyniku.

Użycie złączenia do pobrania par wierszy nie powiązanych wartościami klucza obcego

2.14 Zapytanie odwołuje się do tabel o następującej strukturze:
DOSTAWCY

Id_dostawcy

Nazwa_firmy

Adres

Miasto

Kraj

SKLEPY

Nr_sklepu

Adres

Miasto

Podać wykaz sklepów wraz z danymi dostawców z tego samego miasta

SELECT Sklepy.Nr_sklepu, Sklepy.Miasto, Dostawcy.Nazwa_firmy

FROM Sklepy, Dostawcy

WHERE Sklepy.Miasto = Dostawcy. Miasto ;

To złączenie w istocie definiuje (dynamicznie, w czasie wykonywania programu) takie powiązanie między wierszami dwóch tabel, które nie zostało "zaprogramowane" przez wprowadzenie klucza obcego.

Złączenie zewnętrzne

2.15 Podać pełny wykaz klientów z Krakowa wraz z danymi opisującymi złożone przez nich zamówienia (numer i data). Zakładamy, że są zarejestrowani w bazie danych klienci, dla których nie ma zarejestrowanych zamówień.

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, Zamówienie.Nr_zam,

Zamówienie.Data_zam

FROM Klienci LEFT OUTER JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Klienci.Miasto = Kraków ;

CZĘŚĆ 3 - OBLICZENIA ZBIORCZE

Obliczenia zbiorcze w grupach wierszy we wskazanej tabeli

3.1 Dla każdego klienta podać sumę wartości wszystkich zarejestrowanych zamówień

SELECT Id_klienta, SUM (Wartość_zam) AS Suma_wartości

FROM Zamówienia

GROUP BY Id_klienta ;

3.2 Dla każdego klienta podać średnią wartość zamówienia (policzoną po wszystkich zarejestrowanych zamówieniach pochodzących od tego klienta) i najwyższą wartość zamówienia.

SELECT Id_klienta, AVG(Wartość_zam) AS Średnia_wartość, MAX(Wartość_zam) AS Maks_wartość

FROM Zamówienia

GROUP BY Id_klienta ;

W ramach jednego polecenia SELECT można zlecić wykonanie dwóch lub więcej obliczeń zbiorczych W TYCH SAMYCH GRUPACH WIERSZY.

3.3 Podać średnia cenę dla każdego rodzaju towaru.

SELECT Rodzaj_towaru, AVG(Cena_sprzed) AS Średnia_cena

FROM Towary

GROUP BY Rodzaj_towaru ;

Obliczenie zbiorcze w jednej grupie, zawierającej wszystkie wiersze wskazanej tabeli

3.4 Podać średnią wartość zamówienia (policzoną po wszystkich zarejestrowanych zamówieniach).

SELECT AVG(Wartość_zam) AS Średnia_wartość

FROM Zamówienia ;

Obliczenia zbiorcze w tabeli otrzymanej w wyniku operacji selekcji

3.5 Dla każdego klienta podać sumę wartości zamówień złożonych po 02/01/2004.

Obliczenie zbiorcze jest wykonywane w grupach wierszy dla poszczególnych klientów, w tabeli otrzymanej w wyniku selekcji wg daty zamówienia.

SELECT Id_klienta, SUM (Wartość_zam) AS Suma_wartości

FROM Zamówienia

WHERE Data_zam > '02/01/2004'

GROUP BY Id_klienta ;

3.6 Dla każdego towaru podać liczbę sztuk otrzymaną w dostawach przyjętych po 02/01/2004.

Analogicznie jak w poprzednim zadaniu, obliczenie zbiorcze jest wykonywane w grupach wierszy dla poszczególnych towarów, w tabeli otrzymanej w wyniku selekcji wg daty zamówienia dostawy.

SELECT Nr_towaru, SUM(Ilość) AS Suma_dostaw

FROM Dostawy

WHERE Data_przyjęcia > '02/01/2004'

GROUP BY Nr_towaru ;

3.7 Podać sumę wartości zamówień złożonych po 02/01/2004 przez klienta o identyfikatorze 2345.

Obliczenie zbiorcze jest wykonywane w jednej grupie, zawierającej wszystkie wiersze tabeli otrzymanej w wyniku selekcji wg daty zamówienia i identyfikatora klienta.

SELECT SUM(Wartość_zam) AS Suma_wartości

FROM Zamówienia

WHERE Data_zam > '02/01/2004'

AND Id_klienta = 2345 ;

Obliczenia zbiorcze w tabeli otrzymanej w wyniku sekwencji złączenie- selekcja

3.8 Dla każdego rodzaju towaru podać całkowitą liczbę sztuk towarów tego rodzaju przyjętych w dostawach po 02/01/2004.

SELECT Towary.Rodzaj_towaru, SUM(Dostawy.Ilość) AS Suma_dostaw

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Data_przyjęcia > '02/01/2004'

GROUP BY Towary.Rodzaj_towaru ;

Obliczenie zbiorcze jest wykonywane w kolumnie pochodzącej z tabeli DOSTAWY. Złączenie DOSTAWY-TOWARY jest potrzebne, aby można było pogrupować wiersze wg rodzaju towaru. Dodatkowa operacja selekcji wybiera dostawy z zadanego okresu. Obie te operacje są wykonywane PRZED grupowaniem i obliczeniem zbiorczym.

3.9 Podać całkowitą liczbę sztuk wszystkich namiotów przyjętych w dostawach po 02/01/2004.

SELECT SUM(Dostawy.Ilość) AS Suma_dostaw

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Dostawy.Data_przyjęcia > '02/01/2004'

AND Towary.Rodzaj_towaru = `Namiot' ;

Obliczenie zbiorcze jest wykonywane w kolumnie pochodzącej z tabeli DOSTAWY. Dołączenie wierszy z tabeli TOWARY przed obliczeniem zbiorczym jest potrzebne, aby można było wybrać dostawy dla towarów wskazanego rodzaju, spełniające ponadto warunek nałożony na datę zamówienia dostawy. Obliczenie zbiorcze jest wykonywane w jednej grupie, obejmującej całą tabelę otrzymaną w wyniku sekwencji złączenie-selekcja.

3.10 Dla każdego rodzaju towaru i każdego producenta podać całkowitą liczbę sztuk towarów tego rodzaju przyjętych w dostawach po 02/01/2004.

SELECT Towary.Rodzaj_towaru, Towary.Nazwa_producenta, SUM(Dostawy.Ilość) AS Suma_dostaw

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Dostawy.Data_przyjęcia > '02/01/2004'

GROUP BY Towary.Rodzaj_towaru, Towary.Nazwa_producenta ;

Dołączenie wierszy z tabeli TOWARY jest potrzebne, aby pogrupować wiersze dostaw wg kombinacji (Rodzaj_towaru, Nazwa_producenta). Grupowanie wg kombinacji wartości z dwóch kolumn NIE OZNACZA grupowania 2-poziomowego. Obliczenie zbiorcze jest wykonywane TYLKO dla poszczególnych kombinacji wartości (Rodzaj_towaru, Nazwa_producenta), nie ma obliczenia zbiorczego "wyższego poziomu” dla poszczególnych wartości z kolumny Rodzaj_towaru.

3.11 Dla każdego modelu plecaka podać numer katalogowy i całkowitą liczbę sztuk przyjętych w dostawach po 02/01/2004.

SELECT Towary.Nr_towaru, SUM(Dostawy.Ilość) AS Suma_dostaw

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Dostawy.Data_przyjęcia > '02/01/2004'

AND Towary.Rodzaj_towaru = `Plecak'

GROUP BY Dostawy.Nr_towaru ;

Przed obliczeniem zbiorczym jest potrzebna selekcja wierszy wg warunku nałożonego na datę przyjęcia oraz warunku nałożonego na rodzaj towaru-w celu sprawdzenia tego ostatniego warunku tabelę DOSTAWY złączono z tabelą TOWARY

3.12 Polecenie jak w zad. 3.11, ale każdy wiersz tabeli wynikowej powinien zawierać zarówno numer katalogowy, jak i nazwę producenta oraz oznaczenie modelu.

SELECT Towary.Nr_towaru, Towary.Nazwa_producenta, Towary.Model,

SUM(Dostawy.Ilość) AS Suma_dostaw

FROM Dostawy JOIN Towary ON Dostawy.Nr_towaru = Towary.Nr_towaru

WHERE Dostawy.Data_przyjęcia > '02/01/2004'

AND Towary.Rodzaj_towaru = `Plecak'

GROUP BY Towary.Nr_towaru, Towary.Nazwa_producenta, Towary.Model ;

Grupowanie wg kombinacji (Nr_katalog_towaru, Nazwa_producenta, Model) jest równoznaczne z grupowaniem wg wartości w kolumnie Nr_katalog_towaru. Jednak każda kolumna, która ma być włączona do tabeli wynikowej, oczywiście z wyjątkiem kolumny obliczenia zbiorczego, musi być włączona do kombinacji kolumn określającej grupowanie wierszy.

3.13 Polecenie jak w zad. 3.1, ale wiersz tabeli wynikowej powinien zawierać oprócz identyfikatora klienta również nazwę firmy i miasto. Dla każdego klienta podać: identyfikator, nazwę firmy, miasto oraz sumę wartości wszystkich zarejestrowanych zamówień

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, Klienci.Miasto,

SUM (Wartość_zam) AS Suma_wartości

FROM Zamówienia JOIN Klienci ON Zamówienia.Id_klienta = Klienci.Id_klienta

GROUP BY Klienci.Id_klienta, Klienci.Nazwa_firmy, Klienci.Miasto ;

Analogicznie jak w poprzednim zadaniu, do obliczenia zbiorczego wystarczyłoby grupowanie wg Id_klienta - grupowanie wg kombinacji (Id_klienta, Nazwa_firmy, Miasto) wynika z żądania, aby wszystkie te kolumny były włączone do tabeli wynikowej.

3.14 Dla każdego modelu towaru, na który były składane zamówienia w okresie od 15/04/2004 do 30/04/2004 podać średnią i największą liczbę sztuk zamawianych w ramach jednej pozycji zamówienia. W wierszu wyniku podać pełny opis towaru: numer katalogowy, rodzaj, nazwę producenta i oznaczenie modelu.

SELECT Towary.Nr_towaru, Towary.Rodzaj_towaru, Towary.Nazwa_producenta, Towary.Model,

AVG(Pozycje_zamówień .Ilość_zam) AS (Średnia_ilość),

MAX(Pozycje_zamówień.Ilość_zam) AS (Maks_ilość)

FROM Zamówienia, Pozycje_zamówień, Towary

WHERE Zamówienia.Nr_zam = Pozycje_zamówień.Nr_zam

AND Pozycje_zamówień.Nr_towaru = Towary.Nr_towaru

AND Zamówienia.Data_zam BETWEEN '15/04/2004' AND '30/04/2004'

GROUP BY Towary.Nr_towaru, Towary.Rodzaj_towaru, Towary.Nazwa_producenta, Towary.Model ;

Użycie funkcji zbiorczej COUNT

3.15 Dla każdego miasta, w którym są klienci, podać ich liczbę.

SELECT Miasto, COUNT(*) AS Liczba_klientów

FROM Klienci

GROUP BY Miasto ;

3.16 Podać liczbę klientów z Gdańska.

SELECT COUNT(*) AS Liczba_klientów

FROM Klienci

WHERE Miasto = 'Gdańsk' ;

3.17 Podać, ile zamówień złożył każdy z klientów po 02/01/2004. Wiersz tabeli wynikowej powinien zawierać zarówno identyfikator klienta, jak i nazwę firmy.

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy, COUNT (*) AS Liczba_zamówień

FROM Zamówienia JOIN Klienci ON Zamówienia.Id_klienta = Klienci.Id_klienta

WHERE Zamówienia.Data_zam > `02/01/2004'

GROUP BY Klienci.Id_klienta, Klienci.Nazwa_firmy ;

3.18 Podać, ile zamówień złożyła firma o nazwie `ABC' po 02/01/2004.

SELECT COUNT (*) AS Liczba_zamówień

FROM Zamówienia JOIN Klienci ON Zamówienia.Id_klienta = Klienci.Id_klienta

WHERE Zamówienia.Data_zam > `02/01/2004'

AND Klienci.Nazwa_firmy = `ABC' ;

3.19 Podać w ilu miastach są klienci.

SELECT COUNT (DISTINCT Miasto) AS Liczba_miast

FROM Klienci ;

Obliczenia zbiorcze z selekcją wierszy wyniku - użycie sekcji HAVING

3.20 Podać wykaz modeli plecaków, dla których całkowita ilość zamówiona u wszystkich dostawców w okresie od '15/04/2004' do 14/05/2004' przekracza 2000 sztuk. Dla każdego z nich podać numer katalogowy, nazwę producenta, oznaczenie modelu i całkowitą liczbę sztuk zamówionych u wszystkich dostawców.

SELECT Towary.Nr_towaru, Towary.Nazwa_producenta, Towary.Model, SUM(Dostawy.Ilość_zam) AS Suma_zam

FROM Towary, Dostawy

WHERE Towary.Nr_towaru = Dostawy.Nr_towaru

AND Towary.Rodzaj_towaru = 'Plecak'

AND Dostawy.Data_zam BETWEEN '15/04/2004' AND 14/05/2004'

GROUP BY Towary.Nr_towaru, Towary.Nazwa_producenta, Towary.Model

HAVING SUM(Dostawy.Ilość_zam) > 2000 ;

Tabela wynikowa zawiera te wiersze wyniku obliczenia zbiorczego, w których obliczona suma spełnia zadany warunek

CZĘŚĆ 4 - ZAPYTANIA Z ZAGNIEŻDŻONYMI PODZAPYTANIAMI

PODZAPYTANIA W SEKCJI (KLAUZULI) WHERE

Podzapytania użyte z operatorem IN, NOT IN

4.1 Podać wykaz towarów oferowanych przez dostawcę o numerze identyfikacyjnym 235.

SELECT Rodzaj_towaru, Nazwa_producenta, Model

FROM Towary

WHERE Nr_towaru IN

( SELECT Nr_towaru

FROM Oferty_dostawców

WHERE Id_dostawcy = 235 ) ;

Sformułowanie zadania, które odzwierciedla konstrukcję podaną wyżej jest następujące: podać wykaz towarów, takich że numer katalogowy towaru należy do zbioru numerów katalogowych towarów występujących w ofertach od dostawcy o numerze identyfikacyjnym 235. Zapisane wyżej wyrażenie SELECT jest równoważne wyrażeniu jednopoziomowemu z przykł. 2.8 :

SELECT Towary.Rodzaj_towaru, Towary.Nazwa_producenta, Towary.Model

FROM Towary JOIN Oferty_dostawców

ON Towary.Nr_towaru =

Oferty_dostawców.Nr_towaru

WHERE Oferty_dostawców.Id_dostawcy = 235 ;

4.2 Podać wykaz klientów (identyfikator, nazwa firmy), dla których są zamówienia złożone po 15/04/2004.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE Id_klienta IN

( SELECT DISTINCT Id_klienta

FROM Zamówienia

WHERE Zamówienia.Data_zam > 15/04/2004) ;

Konstrukcja podobna jak w poprzednim zadaniu. Równoważne wyrażenie jednopoziomowe:

SELECT DISTINCT Klienci.Id_klienta, Klienci.Nazwa_firmy

FROM Klienci JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Zamówienia.Data_zam > 15/04/2004 ;

4.3 Podać wykaz klientów (identyfikator, nazwa firmy), dla których nie ma zamówień o wartości większej niż 20 000 złotych.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE Id_klienta NOT IN

( SELECT DISTINCT Id_klienta

FROM Zamówienia

WHERE Zamówienia.Wartość_zam > 20000) ;

Tabela wynikowa zawiera wiersze opisujące klientów, dla których WSZYSTKIE zarejestrowane zamówienia spełniają warunek Wartość_zam < = 20000, oraz wiersze opisujące klientów, dla których w ogóle nie ma zarejestrowanych zamówień. Czy można zapisać to zapytanie w postaci prostego wyrażenia jednopoziomowego?

4.4 Podać wykaz zamówień (numer zamówienia i wartość) złożonych przez klientów z Gdańska w okresie od 15/04/2004 do 30/04/2004.

SELECT Nr_zam, Wartość_zam

FROM Zamówienia

WHERE Zamówienia.Data_zam BETWEEN '15/04/2004' AND '30/04/2004'

AND Id_klienta IN

( SELECT Id_klienta

FROM Klienci

WHERE Klienci.Miasto = 'Gdańsk') ;

Warunek odwołujący się do atrybutu klienta jest zrealizowany przez konstrukcję podobną jak w zad. 4.1, 4.2. Równoważne wyrażenie jednopoziomowe zostało przedstawione w zad. 2.7:

SELECT Zamówienia.Nr_zam, Zamówienia.Wartość_zam

FROM Klienci JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Zamówienia.Data_zam BETWEEN '15/04/2004' AND '30/04/2004'

AND Klienci.Miasto = 'Gdańsk' ;

4.5 Podać wykaz modeli namiotów (nazwa producenta, model), dla których są oferty od dostawców z Niemiec.

SELECT Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru = 'Namiot'

AND Nr_towaru IN

( SELECT DISTINCT Nr_towaru

FROM Oferty_dostawców

WHERE Id_dostawcy IN

( SELECT Id_dostawcy

FROM Dostawcy

WHERE Kraj = 'Niemcy' ) ) ;

Sformułowanie zadania odpowiadające strukturze tego 3-poziomowego wyrażenia SELECT:
podać wykaz modeli namiotów, takich że numer katalogowy danego modelu należy do zbioru numerów katalogowych występujących w ofertach, takich że identyfikator dostawcy należy do zbioru identyfikatorów dostawców z Niemiec

Równoważnym wyrażeniem jednopoziomowym jest zapytanie przedstawione w zad. 2.11:

SELECT Towary.Nazwa_producenta, Towary.Model

FROM Towary, Oferty_dostawców, Dostawcy

WHERE Towary.Nr_towaru = Oferty_dostawców.Nr_towaru

AND Oferty_dostawców.Id_dostawcy = Dostawcy.Id_dostawcy

AND Towary.Rodzaj_towaru = 'Namiot'

AND Dostawcy.Kraj = 'Niemcy' ;

Zauważmy, że w przykładach 4.1-4.5 podzapytanie zwraca tabelę jednokolumnową. Jest to warunek poprawności konstrukcji <wyrażenie skalarne> <operator IN/NOT IN> <podzapytanie>

Podzapytania użyte z operatorem porównania

4.6 Podać wykaz zamówień (numer zamówienia, data) złożonych przez firmę o nazwie JKL po 15/04/2004.

SELECT Nr_zam, Data_zam

FROM Zamówienia

WHERE Data_zam > '15/04/2004'

AND Id_klienta =

( SELECT Id_klienta

FROM Klienci

WHERE Nazwa_firmy = 'JKL' ) ;

Równoważne wyrażenie jednopoziomowe:

SELECT Zamówienie.Nr_zam, Zamówienie.Data_zam

FROM Klienci JOIN Zamówienia ON Klienci.Id_klienta = Zamówienia.Id_klienta

WHERE Data_zam > '15/04/2004'

AND Klienci.Nazwa_firmy = 'JKL' ;

Zauważmy, że użyta w zadaniu 4.6, jak i w następnych przykładach, konstrukcja

<wyrażenie skalarne> <operator_porównania> <podzapytanie>

jest poprawna tylko wtedy, gdy podzapytanie zwraca tabelę jednowierszową, jednokolumnową. Nasuwa się jednak uzasadniona wątpliwość co do poprawności porównania wyrażenia skalarnego z tabelą. Należy więc wyjaśnić, że w tym kontekście wyrażenie skalarne jest interpretowane jako tzw. konstruktor wiersza, który zwraca jeden wiersz z jedną kolumną, zawierający oczywiście (w jedynej kolumnie) wartość wyrażenia.

4.7 Podać wykaz dostawców (identyfikator, nazwa firmy), którzy mają siedzibę w tym samym mieście, co dostawca o nazwie ABC.

SELECT Id_dostawcy, Nazwa_firmy

FROM Dostawcy

WHERE Miasto =

( SELECT Miasto

FROM Dostawcy

WHERE Nazwa_firmy = 'ABC' ) ;

Równoważne wyrażenie jednopoziomowe wymaga wykonania złączenia w ramach jednej tabeli. Zauważmy, jak bardzo "sztucznie" wygląda ta konstrukcja w porównaniu z zapytaniem dwupoziomowym:

SELECT Dost1.Id_dostawcy, Dost1.Nazwa_firmy

FROM Dostawcy Dost1, Dostawcy Dost2

WHERE Dost1.Miasto = Dost2.Miasto

AND Dost2.Nazwa_firmy = 'ABC' ;

4.8 Podać wykaz śpiworów (numer katalogowy, producent, oznaczenie modelu, cena) o cenie niższej niż cena śpiwora Suseł 3 firmy XYZ.

SELECT Nr_towaru, Nazwa_producenta, Model, Cena_sprzed

FROM Towary

WHERE Rodzaj_towaru = 'Śpiwór'

AND Cena_sprzed <

( SELECT Cena_sprzed

FROM Towary

WHERE Rodzaj_towaru = 'Śpiwór'

AND Nazwa_producenta = 'XYZ'

AND Model = 'Suseł 3') ;

4.9 Zapytanie odwołuje się do tabeli o następującej strukturze:

PRACOWNICY

Id_pracownika

Nazwisko

Imię

Stanowisko

Wynagrodzenie

Podać listę pracowników pobierających wynagrodzenie wyższe, niż pracownik o numerze identyfikacyjnym 125.

SELECT Id_pracownika, Nazwisko, Imię

FROM Pracownicy

WHERE Wynagrodzenie >

(SELECT Wynagrodzenie

FROM Pracownicy

WHERE Id_pracownika = 125 ) ;

Podzapytania wykonujące obliczenia zbiorcze, użyte z operatorem porównania

4.10 Podać wykaz modeli plecaków produkcji firmy UWZ, których cena jest wyższa od średniej obliczonej dla wszystkich plecaków.

SELECT Nr_towaru, Model

FROM Towary

WHERE Rodzaj_towaru = 'Plecak'

AND Nazwa_producenta = 'UWZ'

AND Cena_sprzed >

( SELECT AVG (Cena_sprzed)

FROM Towary

WHERE Rodzaj_towaru = 'Plecak' ) ;

Jeszcze raz zauważmy, że porównanie wyrażenia skalarnego z wynikiem podzapytania jest poprawne tylko wtedy, gdy podzapytanie zwraca tabelę jednowierszową, jednokolumnową. Dlatego jeśli w takim kontekście używamy podzapytania wykonującego obliczenie zbiorcze, to może to być tylko obliczenie wykonywane w jednej grupie

4.11 Podać wykaz zamówień (numer zamówienia, identyfikator klienta) z datą późniejszą niż 15/05/2004, o wartości przekraczającej średnią wartość zamówień wszystkich klientów w okresie od 15/04/2004 do 15/05/2004.

SELECT Nr_zam, Id_klienta

FROM Zamówienia

WHERE Data_zam > '15/05/2004'

AND Wartość_zam >

( SELECT AVG (Wartość_zam)

FROM Zamówienia

WHERE Data_zam

BETWEEN '15/04/2004'

AND '15/05/2004') ;

4.12 Podać wykaz klientów, dla których suma wartości zamówień złożonych w ciągu ostatnich 90 dni przekracza 50 000 złotych.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE 50000 <

( SELECT SUM (Wartość_zam)

FROM Zamówienia

WHERE Zamówienia.Id_klienta = Klienci.Id_klienta

AND Sysdate - Zamówienia.Data_zam < = 90 ) ;

Zadanie wymaga zastosowania korelacji między podzapytaniem i zapytaniem zewnętrznym. Korelacja wyraża się odwołaniem w podzapytaniu do tabeli z zapytania zewnętrznego. Podzapytanie jest wykonywane dla każdego rozpatrywanego wiersza tabeli w zapytaniu zewnętrznym - i dla każdego wiersza zwraca w ogólności inny wynik. Tutaj dla każdego wiersza tabeli Klienci, przetwarzanej w zapytaniu zewnętrznym, jest wykonywane podzapytanie obliczające sumę wartości zamówień dla danego klienta (w zadanym okresie czasu)

Poniżej równoważne jednopoziomowe wyrażenie SELECT-obliczenie zbiorcze jest wykonywane w grupach wierszy tabeli otrzymanej ze złączenia tabel Zamówienia i Klienci. Wiersze z tabeli Klienci są potrzebne do uzyskania w wyniku nazwy firmy.

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy

FROM Klienci JOIN Zamówienia ON Zamówienia.Id_klienta = Klienci.Id_klienta

WHERE Sysdate - Zamówienia.Data_zam < = 90

GROUP BY Klienci.Id_klienta, Klienci.Nazwa_firmy

HAVING SUM (Zamówienia.Wartość_zam) > 50000 ;

4.13 Podać wykaz towarów (numer katalogowy, oznaczenie modelu), których cena jest wyższa od średniej obliczonej dla towarów danego rodzaju.

Zadanie pozornie podobne do zadania 4.10, ale tutaj interesują nas towary wszystkich rodzajów, takie że cena towaru jest wyższa od średniej policzonej dla towarów tego samego rodzaju, co rozpatrywany towar.

SELECT Nr_towaru, Model

FROM Towary T1

WHERE Cena_sprzed >

( SELECT AVG (Cena_sprzed)

FROM Towary T2

WHERE T2.Rodzaj_towaru = T1.Rodzaj_towaru ) ;

Podobnie jak w poprzednim zadaniu, trzeba użyć podzapytania skorelowanego z zapytaniem zewnętrznym. W tym przykładzie tabela w zapytaniu zewnętrznym jest tą samą tabelą, co tabela przetwarzana w podzapytaniu, więc trzeba wprowadzić synonimy (T1,T2).Dla każdego wiersza tabeli Towary, przetwarzanej w zapytaniu zewnętrznym, jest wykonywane podzapytanie obliczające średnią cenę dla towarów danego rodzaju.

4.14 Podać numery katalogowe tych artykułów, których zapas w magazynie jest mniejszy niż ilość zamówiona przez klientów w ciągu ostatnich 3 dni.

SELECT Nr_towaru

FROM Towary

WHERE Ilość_w_mag <

( SELECT SUM (Pozycje_zamówień.Ilość_zam)

FROM Pozycje_zamówień JOIN Zamówienia

ON Pozycje_zamówień.Nr_zam =

Zamówienia.Nr_zam

WHERE Sysdate - Zamówienia.Data_zam <= 2

AND Pozycje_zamówień.Nr_towaru = Towary.Nr_towaru ) ;

Dla każdego wiersza tabeli Towary jest wyznaczana suma zamówionych ilości danego towaru z ostatnich 3 dni. Suma jest obliczana w tabeli Pozycje_zamówień - złączenie z tabelą Zamówienia jest potrzebne tylko ze względu na warunek nałożony na datę zamówienia.

4.15 Podać numery zamówień złożonych po 15/04/2004, których wartość przekracza średnią wartość zamówień z tego samego dnia.

SELECT Nr_zam

FROM Zamówienia Zam1

WHERE Data_zam > '15/04/2004'

AND Wartość_zam >

( SELECT AVG (Wartość_zam)

FROM Zamówienia Zam2

WHERE Zam2.Data_zam = Zam1.Data_zam ) ;

Analogicznie jak w zad 4.13, korelacja wymaga wprowadzenia synonimów dla tabeli Zamówienia.

4.16 Podać wykaz modeli namiotów, takich że jest więcej niż 10 klientów, z których każdy zamówił w okresie ostatnich 90 dni więcej niż 50 sztuk danego modelu.

SELECT Nr_towaru, Model

FROM Towary

WHERE Rodzaj_towaru = 'Namiot'

AND 10 <

( SELECT COUNT (*)

FROM Klienci

WHERE 50 <

( SELECT SUM (Pozycje_zamówień.Ilość_zam)

FROM Pozycje_zamówień JOIN Zamówienia

ON Pozycje_zamówień.Nr_zam = Zamówienia.Nr_zam

WHERE Sysdate - Data_zam < = 90

AND Pozycje_zamówień.Nr_towaru = Towary.Nr_towaru

AND Zamówienia.Id_klienta = Klienci.Id_klienta ) ) ;

W tym 3-poziomowym zapytaniu występuje korelacja podzapytania poziomu 3 zarówno z zapytaniem na poziomie 2 (odwołanie do tabeli Klienci), jak i z zapytaniem na poziomie 1 (odwołanie do tabeli Towary). Poniżej sformułowanie zadania odpowiadające strukturze tego 3-poziomowego wyrażenia:

podać wykaz modeli namiotów, takich że jest więcej niż dziesięciu klientów, takich że jest więcej niż 50 sztuk danego modelu zamówionych w sumie w ciągu ostatnich 90 dni przez danego klienta

Podzapytanie użyte z operatorem ALL

4.17 Podać wykaz tych modeli plecaków, których cena jest wyższa niż cena najdroższego śpiwora.

SELECT Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru = 'Plecak'

AND Cena_sprzed > ALL

( SELECT Cena_sprzed

FROM Towary

WHERE Rodzaj_towaru = 'Śpiwór' ) ;

Warunek postaci

<wyrażenie skalarne> <operator porównania> <operator ALL> <podzapytanie>

gdzie podzapytanie zwraca tabelę jednokolumnową, jest spełniony wtedy i tylko wtedy, gdy dla każdego wiersza tabeli zwróconej przez podzapytanie porównanie wyrażenia skalarnego z wartością w tym wierszu przyjmuje wartość logiczną prawda.

Poniżej przedstawiono równoważne zapytanie, w którym zamiast operatora ALL użyto funkcji MAX w podzapytaniu:

SELECT Nazwa_producenta, Model

FROM Towary

WHERE Rodzaj_towaru = 'Plecak'

AND Cena_sprzed >

( SELECT MAX (Cena_sprzed)

FROM Towary

WHERE Rodzaj_towaru = 'Śpiwór'

) ;

Podzapytania użyte z operatorem EXISTS, NOT EXISTS

4.18 Podać wykaz klientów, dla których są zamówienia złożone po 15/04/2004.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE EXISTS

( SELECT *

FROM Zamówienia

WHERE Zamówienia.Id_klienta = Klienci.Id_klienta

AND Data_zam > '15/04/2004'

) ;

Symbol * w tym kontekście jest użyty po to, aby zaznaczyć, że wartość logiczna wyrażenia

EXISTS <podzapytanie>

jest niezależna od tego, jakie kolumny to podzapytanie zwraca.

Zauważmy, że podzapytanie użyte z operatorem EXISTS (również NOT EXISTS) jest z reguły podzapytaniem skorelowanym. Użycie w tym kontekście podzapytania nieskorelowanego byłoby dość niezwykłe - w takim przypadku zapytanie zewnętrzne zwracałoby albo całą tabelę, albo tabelę pustą, zależnie od wyniku podzapytania.

Poniżej równoważne zapytanie, w którym użyto konstrukcji <operator IN> <podzapytanie>. Zauważmy, że podzapytanie nie jest skorelowane z zapytaniem zewnętrznym - zamiast korelacji mamy tutaj sprawdzenie, czy Id_klienta należy do zbioru identyfikatorów z wybranych zamówień.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE Id_klienta IN

( SELECT DISTINCT Id_klienta

FROM Zamówienia

WHERE Data_zam > '15/04/2004' ) ;

Równoważne wyrażenie jednopoziomowe:

SELECT Klienci.Id_klienta, Klienci.Nazwa_firmy

FROM Klienci, Zamówienia

WHERE Klienci.Id_klienta = Zamówienia.Id_klienta

AND Zamówienia.Data_zam > '15/04/2004' ) ;

4.19 Podać wykaz klientów, dla których nie ma zamówień o wartości większej niż 20 000 złotych.

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE NOT EXISTS

( SELECT *

FROM Zamówienia

WHERE Zamówienia.Id_klienta = Klienci.Id_klienta

AND Zamówienia.Wartość_zam > 20000 ) ;

Równoważne zapytanie zawierające konstrukcję <operator NOT IN> <podzapytanie>:

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE Id_klienta NOT IN

( SELECT DISTINCT Id_klienta

FROM Zamówienia

WHERE Wartość_zam > 20000 ) ;

4.20 Podać wykaz artykułów oferowanych przez dostawcę o numerze identyfikacyjnym 235.

SELECT Rodzaj_towaru, Nazwa_producenta, Model

FROM Towary

WHERE EXISTS

( SELECT *

FROM Oferty_dostawców

WHERE Oferty_dostawców.Nr_towaru =

Towary.Nr_towaru

AND Oferty_dostawców.Id_dostawcy = 235

);

Równoważne zapytanie z operatorem IN przedstawiono w zadaniu 4.1, a zapytanie jednopoziomowe-w zadaniu 2.8

4.21 Podać wykaz klientów spełniających następujący warunek: wartość każdego zamówienia od danego klienta przekracza 10000 złotych.

Kwantyfikator ogólny ("dla wszystkich x") zaproponowano dopiero w ramach standardu SQL3. W implementacjach języka, w których kwantyfikator ogólny nie występuje, trzeba skorzystać ze znanych praw logiki (zastąpienie kwantyfikatora ogólnego negacją kwantyfikatora szczegółowego i zanegowanie wyrażenia w zasięgu kwantyfikatora). Powyższe zadanie trzeba sformułować w następujący sposób:

podać wykaz klientów,
dla których NIE ISTNIEJE zamówienie o wartości NIE WIĘKSZEJ niż 10 000 złotych

SELECT Id_klienta, Nazwa_firmy

FROM Klienci

WHERE NOT EXISTS

( SELECT *

FROM Zamówienia

WHERE Zamówienia.Id_klienta = Klienci.Id_klienta

AND Wartość_zam < = 10000 ) ;

Zauważmy, że przyjęto założenie, że dla każdego klienta zarejestrowanego w bazie danych istnieje co najmniej jedno zarejestrowane zamówienie. Jak należałoby rozbudować zapytanie, aby uniknąć błędnego wyniku w przypadku, gdyby to założenie nie było prawdziwe?

4.22 Podać wykaz tych dostawców, którzy oferują wszystkie modele namiotów producenta XYZ.

Analogicznie jak w poprzednim zadaniu, trzeba użyć negacji kwantyfikatora szczegółowego i zanegować wyrażenie w zasięgu kwantyfikatora:

podać wykaz dostawców,
dla których NIE ISTNIEJE model namiotu produkowany przez XYZ (występujący w tabeli TOWARY)
dla którego NIE MA oferty od danego dostawcy.

SELECT Id_dostawcy, Nazwa_firmy

FROM Dostawcy

WHERE NOT EXISTS

( SELECT *

FROM Towary

WHERE Rodzaj_towaru = 'Namiot'

AND Nazwa_producenta = 'XYZ'

AND NOT EXISTS

( SELECT *

FROM Oferty_dostawców

WHERE Oferty_dostawców.Id_dostawcy = Dostawcy.Id_dostawcy

AND Oferty_dostawców.Nr_towaru = Towary.Nr_towaru

)

);

Przyjęto założenie, że istnieje co najmniej jeden model namiotu produkowany przez producenta XYZ, zarejestrowany w bazie danych. Jak należałoby uzupełnić zapytanie, aby uniknąć błędnego wyniku w przypadku, gdyby to założenie nie było prawdziwe?

PODZAPYTANIA W SEKCJI (KLAUZULI) FROM

4.23 Podać najwyższą wartość spośród średnich cen policzonych dla poszczególnych rodzajów towarów.

SELECT MAX (Średnie.Średnia_cena)

FROM (SELECT Rodzaj_towaru, AVG(Cena_sprzed) AS Średnia_cena

FROM Towary

GROUP BY Rodzaj_towaru ) Średnie ;

Podzapytanie zwraca tabelę średnich cen dla poszczególnych rodzajów towarów. Obliczenie zbiorcze w zewnętrznym zapytaniu (funkcja MAX) jest wykonywane na tabeli wynikowej podzapytania

4.24 Dla okresu od 15/04/2004 do 30/04/2004 podać średnią sumę wartości zamówień od jednego klienta, policzoną dla poszczególnych miast.

SELECT Klienci.Miasto, AVG (Sumy.Suma_wartości) AS Średnia_suma

FROM Klienci, (SELECT Id_klienta, SUM(Wartość_zam) AS Suma_wartości

FROM Zamówienia

WHERE Data_zam BETWEEN '15/04/2004' AND '30/04/2004'

GROUP BY Id_klienta) Sumy

WHERE Klienci.Id_klienta = Sumy.Id_klienta

GROUP BY Klienci.Miasto ;

Podzapytanie zwraca tabelę zawierającą sumę wartości zamówień dla każdego klienta. W zapytaniu zewnętrznym wiersze są grupowane wg miasta (w tym celu jest wykonywane złączenie z tabelą Klienci), w każdej grupie jest liczona średnia.

4.25 Podać wykaz towarów (numer katalogowy, oznaczenie modelu), których cena jest wyższa od średniej obliczonej dla towarów danego rodzaju.

Najbardziej "naturalnym" rozwiązaniem jest konstrukcja z podzapytaniem w sekcji WHERE, przedstawiona w zad. 4.13. Inna możliwość to podzapytanie zagnieżdżone w sekcji FROM:

SELECT Towary.Nr_towaru, Towary.Model

FROM Towary, (SELECT Rodzaj_towaru, AVG(Cena_sprzed) AS Średnia_cena

FROM Towary

GROUP BY Rodzaj_towaru ) Średnie

WHERE Towary. Rodzaj_towaru = Średnie. Rodzaj_towaru

AND Towary.Cena_sprzed > Średnie.Średnia_cena ;

Podzapytanie zwraca tabelę zawierającą średnią cenę dla każdego rodzaju towaru. Właściwy (ze względu na rodzaj towaru) wiersz tej tabeli jest dołączany do wiersza tabeli Towary w celu sprawdzenia warunku.

Przykłady zapytań w języku SQL Strona 9 z 18

18



Wyszukiwarka

Podobne podstrony:
Przykładowe poleceniaOpenproj
Przykładowe polecenia Wiersza Poleceń, Notatki, SiS, KL.I
02 Instrukcja SELECT SQL
przykładowe komendy w SQL, STUDIA - Kierunek Transport, STOPIEŃ I, SEMESTR 6, Zastosowanie informaty
polecenia SQL
Linux Komendy i polecenia Praktyczne przykłady
SQL - Przykłady z wykładów, uwm-geodezjaZOD, ROKII, semIII, SIP, SIP ćwiczenia
Instrukcja do poleceń SQL
System informatyczny lasów państwowych zagadnienia i przykładowe pytania, TABELA DO SQL, ID_OB
Windows XP Komendy i polecenia Praktyczne przyklady wxkppp
Linux Komendy i polecenia Praktyczne przyklady
Linux Komendy i polecenia Praktyczne przyklady lkppp
Linux Komendy i polecenia Praktyczne przyklady
SQL Almanach Opis polecen jezyka 2
Windows XP Komendy i polecenia Praktyczne przyklady
Windows XP Komendy i polecenia Praktyczne przyklady 2
Windows 7 Komendy i polecenia Praktyczne przyklady wi7kpp
Windows XP Komendy i polecenia Praktyczne przyklady

więcej podobnych podstron