Radosław Wolicki Kierunek: ETI Rok: III Grupa: II |
Lab. Bazy Danych |
Prowadzący : dr inż. A. Sikorski |
Data Ćwiczenia: 07-01-2013 |
Ćwiczenie nr.13 |
Nr 6
Dzielenie relacyjne, SQL, kwantyfikator ogólny Baza CJDate
1) Uruchomić przykłady podane na wykładzie.
Przykład 1
select * from S
where not exists
(
select * from P
where
P.Color='Red' and
not exists
(select * from SPJ
where SPJ.S#=S.S# and SPJ.P#=P.P#
)
)
Przykład 2
select * from S
where
(
select count (*) from P
where P.Color='Red'
)
=
(
select count(distinct P.P#) from
SPJ join P on P.P#=SPJ.P#
where P.Color='Red' and S.S#=SPJ.S#
)
Przykład 3
select J#,S# from S,J
where
not exists
(select * from SPJ SPJ
where SPJ.S#=S.S# and
not exists
(select * from SPJ SPJ1
where
SPJ1.J#=J.J# and
SPJ1.P#=SPJ.P#
)
)
Przykład 4
select J#,S# from S,J
where
not exists
(select * from SPJ SPJ
where SPJ.S#=S.S# and
not exists
(select * from SPJ SPJ1
where
SPJ1.J#=J.J# and
SPJ1.P#=SPJ.P# and
SPJ1.S#=S.S#
)
)
Przykład 5
select J#,S# from J,S
where
(select count (distinct P#) from SPJ
where SPJ.S#=S.S#) =
(
select count(distinct P#) from SPJ
where
SPJ.J#=J.J#
and
SPJ.P# in
( select P# from SPJ where SPJ.S#=S.S#
)
)
Przykład 6
select J#,S# from J,S
where
(select count (distinct P#) from SPJ
where SPJ.S#=S.S#) =
(
select count(distinct P#) from SPJ
where SPJ.S#=S.S# and
SPJ.J#=J.J#
)
Przykład 7
select J#,S# from J,S
where
(select count (distinct P#) from SPJ
where SPJ.S#=S.S#) =
(
select count(distinct SPJ.P#) from SPJ , SPJ SPJ1
where
SPJ.J#=J.J# and
SPJ.P# =SPJ1.P# and
SPJ1.S#=S.S#
)
2) Zapytania SQL: znaleźć projekty (J) które mają dostawy wszystkich części z Londynu
select J# from J
except
select J# from
(select J#,P# from P,J where P.CITY='London'
except
select J#,P# from SPJ) t
3) Znaleźć pary dostawca projekt (S-J) takie, że dostawca dostarcza wszystkie części wykorzystywane przez projekt
select J#,S# from S,J
where
not exists
(select * from SPJ SPJ
where SPJ.S#=S.S# and
not exists
(select * from SPJ SPJ1
where
SPJ1.J#=J.J# and
SPJ1.P#=SPJ.P#
)
)
W wersji z ''except'':
select J#,S# from S,J
except
select J#,S# from
(
select S.S#,P#,J# from SPJ,S
except
select SPJ1.S#,SPJ2.P#,SPJ2.J# from SPJ SPJ1,SPJ SPJ2
where
SPJ1.J#=SPJ2.J#
) t
4) Pary dostawca projekt takie, że projekt wykorzystuje wszystkie części dostarczane przez danego dostawcę (por. Chris Date uwagi bibliograficzne 6.4 w polskim tłumaczeniu lub 7.48th Edition w angielskojęzycznej)
select J#,S# from S,J
where
not exists
(select * from SPJ SPJ
where SPJ.S#=S.S# and
not exists
(select * from SPJ SPJ1
where
SPJ1.J#=J.J# and
SPJ1.P#=SPJ.P# and
SPJ1.S#=S.S#
)
)
5) Ułożyć zapytania z p. 3,4 w obydwu wersjach tj. podwójna negacja Exists oraz sprawdzanie liczności zbioru
Zapytanie dla Zadania 3:
select J# from J where
not exists(select P# from P where CITY='London' and
not exists(select * from SPJ where SPJ.J#=J.J# and SPJ.P#=P.P#))
6) W zadaniach 7 -11 można posłużyć się tylko jedną techniką – obydwa rozwiązania dla chętnych
???
7) Podaj numery (J#) projektów zaopatrywanych całkowicie przez dostawcę S1 (Date 6.41)
select * from SPJ where S# ='S1'
select distinct J# from SPJ where S#='S1'
8) Podaj numery części (P#) dostarczanych do wszystkich odbiorców w Londynie (Date 6.42)
select P# from P where
not exists(select J# from J where CITY='London' and
not exists(select * from SPJ where SPJ.P# =P.P# and SPJ.J#=J.J#))
9) Podaj numery dostawców dostarczających tę samą część do wszystkich projektów (6.43)
select * from J
select S#,P#,COUNT(distinct J#) from SPJ
group by S#,P#
select * from S where
exists(select SPJ.P# from SPJ where SPJ.S#=S.S# and
not exists (select * from J where
not exists (select * from SPJ spj1 where spj1.J#=J.J# and spj1.P#=SPJ.P# and spj1.S#=S.S#)))
select * from S where
not exists(select * from SPJ spj1,SPJ spj2 where spj1.S#=S.S# and spj2.S#=S.S# and
not exists(select * from SPJ spj3 where SPJ3.S#=S# and spj3.J#=spj2.J# and SPJ3.P#=spj1.P#))
10) Podaj numery dostawców dostarczających wszystkie te same części do wszystkich projektów
select * from S where
not exists(select * from SPJ spj1,SPJ spj2 where spj1.S#=S.S# and spj2.S#=S.S# and
not exists(select * from SPJ spj3 where SPJ3.S#=S# and spj3.J#=spj2.J# and SPJ3.P#=spj1.P#))
11) Podaj numery projektów zaopatrywanych przynajmniej w jedną część dostępną u dostawcy S1 (6.44)
Pierwszy Sposób:
select distinct J# from SPJ where
P# in (select P# from SPJ where S#='s1')
Drugi Sposób:
select distinct spj1.J# from SPJ spj1, SPJ spj2 where
spj2.S#='s1' and spj1.P#=spj2.P#
Baza Northwind
1) Znaleźć CustomerID takich klientów co kupują wszystko
select * from Products p
where
not exists (select * from Customers c where
not exists(
select * from Orders o join [Order Details] od on o.OrderID=od.OrderID
where CustomerID=C.CustomerID and ProductID=p.ProductID
))
2) Znaleźć ProductID produktów dostarczanych do wszystkich klientów
select * from Categories c1
where
not exists (select * from Customers c where
not exists(
select * from Orders o join [Order Details] od on o.OrderID=od.OrderID
join Products p on p.ProductID=od.ProductID
where CustomerID=C.CustomerID and c1.CategoryID=p.CategoryID
)
)
Sprawdzenie że działa:
select * from Customers c
where
not exists (select * from Categories c1 where
not exists(
select * from Orders o join [Order Details] od on o.OrderID=od.OrderID
join Products p on p.ProductID=od.ProductID
where CustomerID=C.CustomerID and c1.CategoryID=p.CategoryID
)
)
3) Zadania analogiczne do p.3 i 4 dla bazy CJDate znaleźć pary pracownik (Employee) klient (Customer) takie, że pracownik obsługuje sprzedaż wszystkich produktów kupowanych przez klienta
with ep as
(select EmployeeID,ProductID from Orders,[Order Details] where Orders.OrderID=[Order Details].OrderID)
select e1.EmployeeID ,e2.EmployeeID from Employees e1, Employees e2
where
not exists (select * from ep where ep.EmployeeID=e1.EmployeeID and
not exists (select * from ep ep1 where ep1.EmployeeID=e2.EmployeeID and ep1.ProductID=ep.ProductID))
and
not exists (select * from ep where ep.EmployeeID=e2.EmployeeID and
not exists (select * from ep ep1 where ep1.EmployeeID=e1.EmployeeID and ep1.ProductID=ep.ProductID))
and
e1.EmployeeID<e2.EmployeeID
with ec as
(select EmployeeID,CategoryID from Orders,[Order Details],Products where Orders.OrderID=[Order Details].OrderID
and [Order Details].ProductID=Products.ProductID)
select e1.EmployeeID ,e2.EmployeeID from Employees e1, Employees e2
where
not exists (select * from ec where ec.EmployeeID=e1.EmployeeID and
not exists (select * from ec ec1 where ec1.EmployeeID=e2.EmployeeID and ec1.CategoryID=ec.CategoryID))
and
not exists (select * from ec where ec.EmployeeID=e2.EmployeeID and
not exists (select * from ec ec1 where ec1.EmployeeID=e1.EmployeeID and ec1.CategoryID=ec.CategoryID))
and
e1.EmployeeID<e2.EmployeeID
4) Takie pary pracownik klient że klient kupuje wszystko co dany pracownik sprzedaje
5) To samo dla kategorii
6) Rozważyć wykorzystanie CTE w celu uproszczenia, zastanowić się, jaka definicja CTE będzie najbardziej sensowna
7) Wybrane zadanie dot. bazy Northwind rozwiązać za pomocą obydwu technik (negacji i zliczania)
Zadanie dodatkowe czyli 7.01.2013
Rozważyć następujący problem: (Date 6.48 tłumaczenie polskie) znaleźć pary dostawców dostarczających te same części. Można zapoznać się z rozwiązaniem w książce. Wskazówka prowadzącego (znacznie prostsze rozwiązanie) . Skorzystać z rozwiązań zadań 3 oraz 4 dot. bazy CJDate. (UWAGA) instrukcja w zasadzie zawiera rozwiązanie – dlatego prowadzący zweryfikuje wyniki dzisiejszego laboratorium.
a) Sposób pierwszy skorzystać w faktu że A=B (AB)- (AB) =0
I zapisać ten fakt przy użyciu SQL-owych działań na zbiorach )
b) Drugi sposób polega na tym żeby dwa razy skorzystać z podwójnej negacji w celu sprawdzenia, czy A sprzedaje wszystko co B (tj. czy A B) oraz czy B sprzedaje wszystko co A , skorzystać z rozwiązania zadań 3 lub 4.
c) Można też rozważyć punkt b z wykorzystaniem zliczania
Ułożyć podobny przykład dla bazy Northwind.
a) Pary klientów kupujących to samo
b) Pary sprzedawców, to samo
c) Oba warianty dla kategorii
d) Rozważyć różne zapisy z zadania dodatkowego dla bazy CJDate
Wskazówka dot. zadania znaleźć takie pary dostawców , że SA dostarcza to wszystko co SB (por. zadanie 3 tam było S-J tutaj S-S)
select sa.S#,sb.S# from S sa, S sb
where
not exists
(select * from SPJ spj1 where spj1.S#=sb.S# and
not exists (select * from SPJ spj2 where spj2.P#=spj1.P# and
spj2.S#=sa.S#))
and sa.S#<>sb.S#
e) Dlaczego ostatni warunek (chodzi o and sa.S#<>sb.S#) ? Czy nie powinno być np.
sa.S#>sb.S# (nie powinno ale odpowiedź uzasadnić).
select sa.S#,sb.S# from S sa, S sb
where
not exists
(select * from SPJ spj1 where spj1.S#=sb.S# and
not exists (select * from SPJ spj2 where spj2.P#=spj1.P# and
spj2.S#=sa.S#))
and sa.S#>sb.S#
ODP: Wynik jest taki sam mimo zmiany ostatniego warunku.
f) Rozważyć zapis ze wskazówki (po punkcie d) z wykorzystaniem notacji z wykładu „amerykańskiego” (Uniwersytet Wisconsin , Lester McCann)
select sa.S#,sb.S# from S sa, S sb where sa.S#<>sb.S#
except
select s1,s2 from
(
select S.S# s1,SPJ.S# s2,SPJ.P# from S,SPJ
except
select SPJ.S#,S.S#,SPJ.P# from S,SPJ
) t
objaśnić powyższe zapytanie oraz wykorzystać w rozwiązaniu
g) Wykorzystać pozostałe 2 notacje z wykładu „amerykańskiego” (i.e. zawieranie się zbiorów oraz zliczanie)
h) (Dodatkowo) zapisać rozwiązanie bezpośrednio korzystając z notacji z podwójnym except (c.f. )rozwiązanie zadania 6.48 z książki. W książce opisano wyprowadzenie rozwiązania z rachunku relacyjnego (podobnie jak McCann) . Wskazówka (schemat do uzupełnienia)
select sa.S#,sb.S# from S sa, S sb
where
not exists
(select * from SPJ spj1 where spj1.S#=sb.S# and
not exists (select * from SPJ spj2 where spj2.P#=spj1.P# and
spj2.S#=sa.S#))
and
not exists
(select * from SPJ spj1 where spj1.S#=sa.S# and
not exists (select * from SPJ spj2 where spj2.P#=spj1.P# and
spj2.S#=sb.S#))
and
sb.S#<>sa.S#
Uzasadnić powyższy schemat. Pokazać, że w istocie jest to pierwsza wskazówka (AB)- (AB) .
i) Rozważyć rozwiązanie w c# (np. na serwerze aplikacji z wykorzystaniem prostszych SQL) – powiedzmy „chwilowy zanik pomysłowości” –zamiast SQL pętle. Do zrobienia w lab.
j) Zadanie 8.11.48 z książki – pozostawione czytelnikowi (e.g. studentom)
k) Zadanie na przyszły tydzień będzie polegało na uzupełnieniu bazy danych w taki sposób by zbiór wynikowy był niepusty.
Wskazówki:
1) Rozważyć przykład dot. eksploracji danych
select CategoryName,
( select Sum(Quantity*od.UnitPrice) from [Order Details] od,Orders
o,Products p where
o.OrderID=od.OrderId and year(o.OrderDate)=1996 and
p.ProductID=od.ProductID and
p.CategoryID=c.categoryID ) as "1996",
( select Sum(Quantity*od.UnitPrice) from [Order Details] od,Orders
o,Products p where
o.OrderID=od.OrderId and year(o.OrderDate)=1997 and
p.ProductID=od.ProductID and
p.CategoryID=c.categoryID ) as "1997",
( select Sum(Quantity*od.UnitPrice) from [Order Details] od,Orders
o,Products p where
o.OrderID=od.OrderId and year(o.OrderDate)=1998 and
p.ProductID=od.ProductID and
p.CategoryID=c.categoryID ) as "1998 "
from
Categories c
Uruchomić w Management Studio.
2) Deklaracja tabelki powinna zawierać 3 kolumny o typie stałoprzecinkowym numeric(10,2)
create table YearCategoryStat
(
"1996" numeric(10,2),
"1997" numeric(10,2),
"1998" numeric(10,2)
)
3) W Visual studio utworzyć aplikację konsolową i uruchomić poniższy przykład
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("Data Source=.;Initial
Catalog=Northwind;Integrated Security=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand(
"select CategoryName, ( select Sum(Quantity*od.UnitPrice) from [Order
Details] od,Orders o,Products p where " +
"o.OrderID=od.OrderId and year(o.OrderDate)=1996 and
p.ProductID=od.ProductID and " +
"p.CategoryID=c.categoryID ) as [1996], " +
"( select Sum(Quantity*od.UnitPrice) from [Order Details] od,Orders
o,Products p where " +
"o.OrderID=od.OrderId and year(o.OrderDate)=1997 and
p.ProductID=od.ProductID and " +
"p.CategoryID=c.categoryID ) as [1997], " +
"( select Sum(Quantity*od.UnitPrice) from [Order Details] od,Orders
o,Products p where " +
"o.OrderID=od.OrderId and year(o.OrderDate)=1998 and
p.ProductID=od.ProductID and " +
"p.CategoryID=c.categoryID ) as [1998] from Categories c", conn
);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
for (int i = 0; i < rdr.FieldCount; i++)
{
Console.Write(rdr.GetValue(i));
Console.Write("\t");
}
Console.WriteLine();
}
conn.Close();
}
}
}
4) Przeprowadzić eksperymenty z zapytaniami ze sprawozdań (lub z wykładów jeśli ktoś nie oddaje sprawozdań)
5) Zastąpić wypisywanie na konsolę poleceniami insert , posłużyć się funkcją ExecuteNonQuery
6) (Dodatkowo) spróbować wygenerować programowo polecenie create table na podstawie analizy zbioru wynikowego. Rozważyć poniższy fragment kodu:
SqlDataReader rdr = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rdr.FieldCount; i++)
{
sb.AppendFormat("{0} {1},",
new object[] {
rdr.GetName(i),rdr.GetDataTypeName(i)}
);
sb.AppendLine();
}
Polecenia aktualizujące stan bazy danych c.d.
16) Ustalić adres IP maszyny wskazanej przez prowadzącego i nawiązać połączenie sieciowe z serwerem bd. (użytkownik/xyz xyz) Wyjaśnić dlaczego w przypadku sieci korzystającej z DHCP adres ten nie jest znany z góry. Następne polecenia wykonywać tylko wskazanym na serwerze.
17) Polecenie podnoszące cenę 3 najlepiej sprzedających się produktów o 10%. Rozważyć różne (przynajmniej 2 postaci tego polecenia)
18) Podobnie jak 17, polecenie podnoszące cenę wszystkich produktów z kategorii najlepiej sprzedających się produktów.
19) Dodać nową kategorię wraz z zestawem produktów. Dodać do bazy zamówienia po 1 sztuce dla wszystkich klientów z Niemiec.
20) Dodać w tabelce Employees pole TotalSales i wypełnić odpowiednimi danymi.
21) GroupOn Powiedzmy, że Northwind weszło w kontakt z GroupOn. Dodać odpowiednie tabelki , wypełnić pola danymi. Założyć, że groupon zostanie wprowadzony do bazy przed złożeniem zamówienia. Klient może mieć wiele groupon’ów. Rozważyć wybrane) sytuacje:
a. groupon dotyczyć może pojedynczego zamówienia,
b. dotyczy pojedynczego zamówienia i tylko pewnej grupy produktów
c. ustalony na grouponie jest pewien limit kwotowy, może być rozliczony i wykorzystany przy składaniu wielu zamówień
d. jak w podpunkcie c ale z ograniczeniami z podp. B
e. każdy produkt może mieć podany upust lub alternatywnie upusty są zawarte w grouponie.
22) Uruchomić przykłady aplikacji bazodanowych korzystających z okienek. Przeanalizować kod – dobra znajomość użytych mechanizmów będzie potrzebna przy realizacji dalszych laboratoriów.