Tagi: exists

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]