Tagi: Northwind

Zadanie 6.

1. Stwórz tabelę zawierającą pola: Imię, Nazwisko, Pesel, Data, gdzie Pesel będzie kluczem głównym; żadne z pól nie może być puste, z wyjątkiem Daty. Dobierz odpowiednie typy danych.

2. Uzupełnij tabelę danymi (dane w pełni fikcyjne, wymyślone na potrzeby ćwiczenia):

('Anna', 'Braun', '70010112365'),
('Celia', 'Donut', '74011112365'),
('Ellie', 'Fine', '85101512365'),
('Gloria', 'Hint', '79051412369'),
('Ian', 'Johnson', '82021685214'),
('Kelly', 'Long', '64081725874'),
('Merry', 'Nice', '89120425896');

3. Wypełnij kolumnę Data danymi – ma się w niej znaleźć data urodzenia danej osoby, ustalona na podstawie numeru pesel.

Baza: Northwind, Tabela: PeselTab (Twoja tabela), kolumny: Imie, Nazwisko, Pesel, Data, Wynik: 7 rows

z6

 

 

 

 

 

Rozwiązanie

1. USE Northwind;

CREATE TABLE PeselTab (
Imie VARCHAR(20) NOT NULL,
Nazwisko VARCHAR(25) NOT NULL,
Pesel VARCHAR(11) PRIMARY KEY,
Data DATE );

2. INSERT INTO  PeselTab(Imie, Nazwisko, Pesel) VALUES
('Anna', 'Braun', '70010112365'),
('Celia', 'Donut', '74011112365'),
('Ellie', 'Fine', '85101512365'),
('Gloria', 'Hint', '79051412369'),
('Ian', 'Johnson', '82021685214'),
('Kelly', 'Long', '64081725874'),
('Merry', 'Nice', '89120425896');

3. UPDATE PeselTab
SET Data = CAST(SUBSTRING(Pesel, 1, 6) as DATE);

[collapse]

 

Zadanie 5.

1. Utwórz tabelę ProductDiscount (ProductID, UnitPrice, Discount). Klucz główny ustaw na ProductID, a pole Discount domyślnie ma wartość 0.

Utwórz również tabelę ArchiwumPD (ProductID, OldDiscount, NewDiscount).

2. Wypełnij tabelę ProductDiscount danymi z tabeli Products (ProductID, UnitPrice).

3. Ustal rabat 9% dla 10 najdroższych produktów, oraz 6% dla kolejnych pięciu. Zarówno nowe jak i stare wartości rabatu wraz z id produktu przenieś do tabeli ArchiwumPD.

4. Dodaj kolumnę NewPrice, która przechowywać będzie cenę produktu po rabacie. Jeśli produkt nie ma przyznanego rabatu, w polu NewPrice widnieć powinno zero.

5. Przywróć wcześniejsze wartości rabatów dla produktów 7-12 (wzgl. ceny).

Baza: Northwind, Tabele: dbo.ProductDiscount, dbo.ArchiwumPD, Kolumny: ProductID, UnitPrice, Discount, NewPrice, OldDiscount, NewDiscount

z5

 

 

 

 

 

 

 

 

Rozwiązanie

1. CREATE TABLE dbo.ProductDiscount (
ProductID INT PRIMARY KEY,
UnitPrice INT NOT NULL,
Discount NUMERIC(4,3) DEFAULT 0
);

CREATE TABLE dbo.ArchiwumPD (
ProductID INT PRIMARY KEY,
OldDiscount NUMERIC(4,3),
NewDiscount NUMERIC(4,3)

);

2. INSERT INTO dbo.ProductDiscount (ProductID, UnitPrice)
SELECT ProductID, UnitPrice
FROM dbo.Products;

3. Dla pierwszych 10:

WITH CTE AS (
SELECT ProductID, UnitPrice, Discount
FROM dbo.ProductDiscount
ORDER BY UnitPrice DESC
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY
)

UPDATE CTE
SET Discount = 0.09
OUTPUT
deleted.ProductID,
deleted.Discount,
inserted.Discount
INTO dbo.ArchiwumPD(ProductID, OldDiscount, NewDiscount);

I kolejne 5:

WITH CTE AS (
SELECT ProductID, UnitPrice, Discount
FROM dbo.ProductDiscount
ORDER BY UnitPrice DESC
OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY
)

UPDATE CTE
SET Discount = 0.06
OUTPUT
deleted.ProductID,
deleted.Discount,
inserted.Discount
INTO dbo.ArchiwumPD(ProductID, OldDiscount, NewDiscount);

Lub z wykorzystaniem tabeli pochodnej (analogicznie będzie przy 10 najdroższych produktach):

UPDATE dbo.ProductDiscount
SET Discount = 0.06
OUTPUT
deleted.ProductID,
deleted.Discount,
inserted.Discount
INTO dbo.ArchiwumPD(ProductID, OldDiscount, NewDiscount)
WHERE ProductID IN (SELECT ProductID
FROM dbo.ProductDiscount
ORDER BY UnitPrice DESC
OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY);

4. ALTER TABLE dbo.ProductDiscount
ADD NewPrice NUMERIC(5,2);

UPDATE dbo.ProductDiscount
SET NewPrice = UnitPrice*(1 - Discount);

UPDATE dbo.ProductDiscount
SET NewPrice = 0
WHERE Discount = 0;

5. WITH CTE AS (
SELECT PD.Discount as Disc, APD.OldDiscount as OldDisc
FROM dbo.ProductDiscount as PD LEFT JOIN dbo.ArchiwumPD as APD
on PD.ProductID = APD.ProductID
ORDER BY UnitPrice DESC
OFFSET 6 ROWS FETCH NEXT 6 ROWS ONLY
)

UPDATE CTE
SET Disc = OldDisc;

I aktualizujemy ceny w kolumnie NewPrice:

UPDATE dbo.ProductDiscount
SET NewPrice = UnitPrice*(1 - Discount);

UPDATE dbo.ProductDiscount
SET NewPrice = 0
WHERE Discount = 0;

[collapse]

Zadanie 4.

1. Skopiuj tabelę dbo.Orders za pomocą SELECT INTO (tworząc tabelę dbo.Ord2).

2. Tabeli dbo.Ord2 przypisz klucz główny na kolumnie OrderID

3. Dodaj kolumnę ShipDelay, w której określimy, czy towar został dostarczony na czas.

4. Wypełnij kolumnę ShipDelay danymi (RequiredDate – ShippedDate)

5. Zmodyfikuj tabelę wstawiając 0 (zero) tam, gdzie nie było opóźnień w dostawie.

6. Sprawdź, czy są klienci którzy dostali towar z opóźnieniem, oraz czy złożyli jeszcze jakieś zamówienia (później).

Baza: Northwind, Tabela: dbo.Orders / Ord2, Kolumny: CustomerID, OrderID, RequiredDate, ShippedDate, ShipDelay, Wynik: klienci, którzy złożyli kolejne zamówienia po otrzymaniu dostawy z opóźnieniem: 33, Klienci, którzy po opóźnionej dostawie nie złożyli już zamówień: 4, Klienci, którzy po pierwszym opóźnieniu złożyli kolejne zamówienie, ale po drugim już nie: 1

Rozwiązanie

1.

USE Northwind;

SELECT *
INTO dbo.Ord2
FROM dbo.Orders;

2.

ALTER TABLE dbo.Ord2
ADD CONSTRAINT OrderID_pk PRIMARY KEY (OrderID);

3.

ALTER TABLE dbo.Ord2
ADD ShipDelay INT;

4.

WITH CTE AS (
SELECT OrderID, CustomerID, RequiredDate, ShippedDate, ShipDelay, DATEDIFF(day, RequiredDate, ShippedDate) as DaysDelay
FROM dbo.Ord2
)

UPDATE CTE
SET ShipDelay = DaysDelay;

5.

UPDATE dbo.Ord2
SET ShipDelay = 0
WHERE ShipDelay <= 0;

Albo z użyciem wyrażeń tablicowych:

WITH CTE2 AS (
SELECT ShipDelay,
CASE
WHEN ShipDelay <= 0 THEN 0
ELSE ShipDelay
END AS SD

FROM dbo.Ord2
)

UPDATE CTE2
SET ShipDelay = SD;

6. Klienci, którzy złożyli kolejne zamówienia po otrzymaniu dostawy z opóźnieniem:

SELECT CustomerID, OrderID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
);

 

Klienci, którzy po opóźnionej dostawie nie złożyli już zamówień:

SELECT CustomerID, OrderID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND NOT EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
);

 

Klienci, którzy po pierwszym opóźnieniu złożyli kolejne zamówienie, ale po drugim już nie:

SELECT CustomerID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
)

INTERSECT

SELECT CustomerID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND NOT EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
);

 

[collapse]

Zadanie 26.

Wybierz wszystkich klientów, którzy zamówili produkty o id 1 i 55. Zadanie rozwiąż na dwa sposoby.

Baza: Northwind, Tabele: dbo.Order Details, dbo.Orders, Kolumny: CustomerID, OrderID, ProductID, Wynik: 16 rows

s26

Rozwiązanie

1. Z użyciem podzapytań i Exists:

SELECT DISTINCT O.CustomerID
FROM dbo.[Order Details] OD JOIN dbo.Orders O
ON OD.OrderID = O.OrderID
WHERE OD.ProductID = 1
AND EXISTS (
SELECT *
FROM dbo.[Order Details] OD2 JOIN dbo.Orders O2
ON OD2.OrderID = O2.OrderID
WHERE O.CustomerID = O2.CustomerID
AND OD2.ProductID = 55
)
ORDER BY O.CustomerID;

2. Z użyciem operatorów zbiorowych:

SELECT O.CustomerID
FROM dbo.[Order Details] OD JOIN dbo.Orders O
ON OD.OrderID = O.OrderID
WHERE OD.ProductID = 1

INTERSECT

SELECT O.CustomerID
FROM dbo.[Order Details] OD JOIN dbo.Orders O
ON OD.OrderID = O.OrderID
WHERE OD.ProductID = 55

ORDER BY O.CustomerID;

[collapse]

Zadanie 24.

Wcielmy w życie zasadę Pareto (zasada 80/20). Mówi ona, że tylko ok. 20% klientów firmy odpowiada za ok. 80% jej przychodów. Sprawdźmy, czy podobna relacja zachodzi i tu.

1. Utwórz zapytanie, które zwróci nazwę firmy, łączną wartość zamówień firmy, łączną ogólną wartość zamówień.

2. Zmodyfikuj zapytanie tak, by zwracało również procentowy udział wartości zamówień danej firmy.

3. Powyższe zapytanie zmodyfikuj jeszcze raz, tak, aby pokazywało również zsumowane punkty procentowe (poczynając od najwyższych wartości).

Baza: Northwind, Tabela: Sales Totals by Amount (widok), Kolumny: CompanyName, SaleAmount, Wynik: 31 rows

s24

 

 

 

 

Rozwiązanie

1. SELECT DISTINCT CompanyName, SUM(SaleAmount) OVER(PARTITION BY CompanyName) as TotalByCust, SUM(SaleAmount) OVER() as Total
FROM dbo.[Sales Totals by Amount];

 

2. SELECT DISTINCT CompanyName, SUM(SaleAmount) OVER(PARTITION BY CompanyName) as TotalByCust, SUM(SaleAmount) OVER() as Total,
CAST(100. * SUM(SaleAmount) OVER(PARTITION BY CompanyName) / SUM(SaleAmount) OVER() as DECIMAL(5,2)) as Pct
FROM dbo.[Sales Totals by Amount];

 

3. WITH CTE AS (
SELECT DISTINCT CompanyName, SUM(SaleAmount) OVER(PARTITION BY CompanyName) as TotalByCust, SUM(SaleAmount) OVER() as Total,
CAST(100. * SUM(SaleAmount) OVER(PARTITION BY CompanyName) / SUM(SaleAmount) OVER() as DECIMAL(5,2)) as Pct
FROM dbo.[Sales Totals by Amount]
)

SELECT CompanyName, TotalByCust, Total, Pct, SUM(Pct) OVER(ORDER BY Pct DESC) as PctSum
FROM CTE
ORDER BY Pct DESC;

[collapse]

Zadanie 23.

Korzystając z widoku Sales Totals by Amount, utwórz zapytanie, które zwróci nazwę firmy, numer zamówienia, wartość zamówienia, procentowy udział zamówienia oraz łączną wartość zamówień klienta.

Baza: Northwind, Tabela: dbo.Sales Totals by Amount (widok), Kolumny: CompanyName, OrderID, SaleAmount, Wynik: 66 rows

s23

 

 

 

 

Rozwiązanie

SELECT CompanyName, OrderID, SaleAmount,
CAST(100. * SaleAmount / SUM(SaleAmount) OVER(PARTITION BY CompanyName) as DECIMAL(5,2)) as 'Percent',
SUM(SaleAmount) OVER(PARTITION BY CompanyName) as TotalByCust
FROM dbo.[Sales Totals by Amount]
ORDER BY CompanyName;

[collapse]

Zadanie 20.

1. Utwórz wspólne wyrażenie tablicowe (CTE), które zwróci nazwy miast i państw, w których są zarówno klienci jak i dostawcy.

2. W ostatecznym wyniku zapytania chcemy zobaczyć klientów i dostawców (CompanyName, SupplierID / CustomerID) z miast określonych w wyrażeniu tablicowym.

Baza: Northwind, Tabele: dbo.Suppliers, dbo.Customers, Kolumny: City, Country, CompanyName, SupplierID, CustomerID, Wynik: 14 rows

s20

 

 

 

 

 

Rozwiązanie

WITH CTE AS (

SELECT Country, City
FROM dbo.Suppliers

INTERSECT

SELECT Country, City
FROM dbo.Customers

)

SELECT s.SupplierID, s.CompanyName, s.City, c.CustomerID, c.CompanyName
FROM dbo.Suppliers as s JOIN dbo.Customers as c on s.City = c.City
WHERE s.City in (SELECT City FROM CTE);

[collapse]

Zadanie 19.

Wskaż, w których państwach i miastach (Country, City):

a) mają siedziby zarówno klienci, jak i dostawcy

b) mają siedziby dostawcy i klienci, ale nie pracownicy

c) są zarówno klienci i pracownicy, ale nie ma dostawców

Baza: Northwind, Tabele: dbo.Customers, dbo.Suppliers, dbo.Employees, Kolumny: Country, City, Wynik: a) 5 rows, b) 90 rows, c) 2 rows

Rozwiązanie

a) SELECT Country, City
FROM dbo.Customers

INTERSECT

SELECT Country, City
FROM dbo.Suppliers

 

b) SELECT Country, City
FROM dbo.Customers

UNION

SELECT Country, City
FROM dbo.Suppliers

EXCEPT

SELECT Country, City
FROM dbo.Employees

 

c) (SELECT Country, City
FROM dbo.Customers

EXCEPT

SELECT Country, City
FROM dbo.Suppliers)

INTERSECT

SELECT Country, City
FROM dbo.Employees

lub

SELECT Country, City
FROM dbo.Customers

INTERSECT

SELECT Country, City
FROM dbo.Employees

EXCEPT

SELECT Country, City
FROM dbo.Suppliers

[collapse]

Zadanie 18.

1. Stwórz kwerendę, która zwróci nazwę firmy, kraj oraz miasto klientów oraz dostawców.

2. Zmodyfikuj kwerendę tak, by pokazywała również kto jest dostawcą, a kto klientem. Wynik posortuj według typu (klienci najpierw), kraju i miasta.

Baza: Northwind, Tabele: dbo.Customers, dbo.Suppliers, Kolumny: CompanyName, Country, City, Wynik: 120 rows

s18

 

 

 

Rozwiązanie

1. SELECT CompanyName, Country, City
FROM dbo.Customers

UNION ALL

SELECT CompanyName, Country, City
FROM dbo.Suppliers

 

2. SELECT 'Customer' as 'Type', CompanyName, Country, City
FROM dbo.Customers

UNION ALL

SELECT 'Supplier' as 'Type', CompanyName, Country, City
FROM dbo.Suppliers

ORDER BY Type, Country, City

[collapse]

Zadanie 17.

1. Utwórz wspólne wyrażenie tablicowe (CTE), nazwane SalesSummary, które wyświetli nam szereg informacji o zamówieniach (OrderID, SaleAmount, CompanyName, ProductID, ProductName, UnitPrice, Quantity, Discount, ExtendedPrice, ShippedDate). Użyj w tym celu widoków Sales Totals by Amount oraz Order Details Extended.

2. W kwerendzie zewnętrznej wybierz wszystkie kolumny tabeli SalesSummary, oraz dołóż kolumnę zawierającą ID klienta (CustomerID, z tabeli Customers).

Baza: Northwind, Tabele: dbo.Sales Totals by Amount (widok), dbo.Order Details Extended (widok), dbo.Customers, Kolumny: OrderID, SaleAmount, CompanyName, ProductID, ProductName, UnitPrice, Quantity, Discount, ExtendedPrice, ShippedDate, CustomerID, Wynik: 233 rows

s17

 

 

Rozwiązanie

1. WITH SalesSummary AS
(
SELECT s.OrderID, s.SaleAmount, s.CompanyName, o.ProductID, o.ProductName, o.UnitPrice, o.Quantity, o.Discount, o.ExtendedPrice,  s.ShippedDate
FROM dbo.[Sales Totals by Amount] as s
JOIN dbo.[Order Details Extended] as o on s.OrderID = o.OrderID
)

2. SELECT *, (SELECT c.CustomerID FROM dbo.Customers as c WHERE SalesSummary.CompanyName = c.CompanyName) as CustomerID
FROM SalesSummary
ORDER BY OrderID;

[collapse]
« Starsze wpsiy