Tagi: INTERSECT

Zadanie 8.

Napisz kwerendę, która zwróci listę nazwisk, które noszą zarówno klienci, jak i pracownicy.

Schemat: OE, HR, Tabele: Employees, Customers, Kolumny: cust_last_name, last_name, Wynik: 6 rows

s8

 

 

 

 

Rozwiązanie

1. Z operatorem INTERSECT:

SELECT DISTINCT last_name FROM HR.employees
INTERSECT
SELECT cust_last_name FROM customers;

2. Z użyciem EXISTS:

SELECT DISTINCT last_name FROM HR.employees
WHERE EXISTS (
SELECT cust_last_name
FROM customers
WHERE HR.employees.last_name = customers.cust_last_name );

[collapse]

Zadanie 1.

Korzystając z tabeli Order_Items znajdź te zamówienia, które zawierają produkty o id 3127 i 3106 (oba jednocześnie). Zadanie rozwiąż na co najmniej dwa sposoby.

Schemat: OE, Tabela: Order_Items, Kolumny: order_id, product_id, Wynik: 13 rows

s1

 

 

 

 

 

 

 

 

 

Rozwiązanie

1. Z użyciem INTERSECT:

SELECT order_id
FROM order_items
WHERE product_id = 3127

INTERSECT

SELECT order_id
FROM order_items
WHERE product_id = 3106

ORDER BY order_id;

2. Z użyciem EXISTS:

SELECT order_id
FROM order_items oi
WHERE product_id = 3127
AND EXISTS (
SELECT order_id
FROM order_items oi2
WHERE product_id = 3106 AND oi.order_id = oi2.order_id
)
ORDER BY order_id;

3. Z użyciem IN:

SELECT order_id
FROM order_items
WHERE product_id = 3127
AND order_id IN
( SELECT order_id FROM order_items WHERE product_id = 3106);

4. Z użyciem klauzuli WITH:

WITH Subquery AS (
SELECT order_id
FROM order_items
WHERE product_id = 3127 OR product_id = 3106
)

SELECT *
FROM Subquery
GROUP BY order_id
HAVING COUNT(*) >1
ORDER BY order_id;

5. Z podzapytaniem w klauzuli FROM:

SELECT order_id
FROM (
SELECT order_id
FROM order_items
WHERE product_id = 3127 OR product_id = 3106
) Tab
GROUP BY order_id
HAVING COUNT(*) >1
ORDER BY order_id;

[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 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]