Zadanie 3.

Korzystając z tabeli Customers, policz, ile jest kobiet, a ilu mężczyzn. Wynik podaj w liczbach oraz procentach.

Schemat: OE, Tabela: Customers, Kolumny: gender, Wynik: 2 rows

s3

 

 

Rozwiązanie

SELECT gender, COUNT(*) AS "Count",
CAST(100* COUNT(*)/SUM(COUNT(*)) OVER() AS NUMBER(5,2)) AS "Percent"
FROM customers
GROUP BY gender;

[collapse]

Zadanie 2.

Czy więcej zamówień było złożonych przed godziną 14, czy później?

Schemat: OE, Tabela: Orders, Kolumny: order_id, order_date, Wynik: 2 rows

s2

 

 

 

Rozwiązanie

WITH

Przed14 AS (
SELECT COUNT(order_id) as Zamowienia, EXTRACT(hour from order_date) as Godzina
FROM orders
WHERE EXTRACT(hour from order_date) < 14
GROUP BY EXTRACT(hour from order_date)
),

Po14 AS (
SELECT COUNT(order_id) as Zamowienia, EXTRACT(hour from order_date) as Godzina
FROM orders
WHERE EXTRACT(hour from order_date) >= 14
GROUP BY EXTRACT(hour from order_date)
)

SELECT 'Zamowienia przed godz 14: '||SUM(Zamowienia) as wynik FROM Przed14
UNION
SELECT 'Zamowienia po godz 14: '||SUM(Zamowienia) FROM Po14;

[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 24.

Dla zamówień o numerach 2355, 2413, 2377 i 2361 policz:

a) ile produktów zawiera każde z nich oraz podaj średnią cenę produktu

b) podaj kraj, z którego zostało złożone zamówienie; ile zamówień ma na koncie klient, który je złożył?

Schemat: OE, Tabele: Orders, Customers, Order_Items, Kolumny: order_id, product_id, unit_price, nls_territory, Wynik: 4 rows

Rozwiązanie

a) SELECT order_id, COUNT(product_id) as Products, to_char(AVG(unit_price), '999D99')as Avg_Price
FROM orders o INNER JOIN order_items oi USING(order_id)
WHERE order_id IN(2355, 2413, 2377, 2361)
GROUP BY order_id;

b) SELECT customer_id, MIN(c.nls_territory) as Country, COUNT(o.order_id) as Orders
FROM orders o INNER JOIN customers c USING(customer_id)
WHERE o.order_id IN(2355, 2413, 2377, 2361)
GROUP BY customer_id;

[collapse]

Zadanie 22.

Dla każdego klienta, który złożył zamówienie, określ średnią wartość zamówienia. Ponumeruj klientów wg najwyższej średniej wartości zamówienia.

Schemat: OE, Tabele: Customers, Orders, Kolumny: customer_id, order_total, Wynik: 47 rows

p22

 

 

 

 

 

Rozwiązanie

SELECT customer_id, AVG(o.order_total) as "Avg Order Value", ROW_NUMBER() OVER(ORDER BY AVG(o.order_total) DESC) as Num
FROM orders o INNER JOIN customers c
USING(customer_id)
GROUP BY customer_id
ORDER BY Num;

[collapse]

Zadanie 21.

Dla klientów o ID 101, 111, 121, 141, 171 i 201 pokaż numer oraz datę ostatniego złożonego zamówienia. Jeśli klient nie ma na swoim koncie zamówień, powinna pojawić się stosowna informacja.

Schemat: OE, Tabele: Orders, Customers, Kolumny: customer-id, order_id, order_date, Wynik: 6 rows

p21

 

 

Rozwiązanie

SELECT customer_id as Customer, MAX(o.order_id) as "Last order",
to_char(MAX(o.order_date), 'DD.MM.YYYY') as "Last ord. date",
CASE
WHEN MAX(o.order_id) IS NULL THEN 'Ten klient nie ma zamówień'
ELSE ' '
END as Opis
FROM customers c LEFT OUTER JOIN orders o
USING(customer_id)
WHERE customer_id IN(101, 111, 121, 141, 171, 201)
GROUP BY customer_id
ORDER BY customer_id;

[collapse]

Zadanie 20.

Pokaż klientów o parzystym ID, którzy złożyli więcej niż 3 zamówienia lub nie złożyli żadnego.

Schemat: OE, Tabele: Orders, Customers, Kolumny: customer_id, order_id, Wynik: 138 rows

p20

 

 

 

 

Rozwiązanie

SELECT customer_id as Customer, COUNT(order_id) as Orders
FROM customers c LEFT OUTER JOIN orders o
USING(customer_id)
WHERE MOD(customer_id, 2) = 0
GROUP BY customer_id
HAVING COUNT(order_id) >= 3 OR COUNT(order_id) = 0
ORDER BY customer_id;

[collapse]

Zadanie 19.

Określ, ile produktów (product_id) zawiera które zamówienie; wynik opisz przedziałami: “Jeden lub dwa”, “Od trzech do pięciu”, “Od sześciu do dziesięciu”, “Powyżej dziesięciu”.

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

p19

 

 

 

 

 

Rozwiązanie

SELECT order_id,
CASE
WHEN COUNT(product_id) <=2 THEN 'Jeden lub dwa'
WHEN COUNT(product_id) BETWEEN 3 AND 5 THEN 'Od trzech do pięciu'
WHEN COUNT(product_id) BETWEEN 6 AND 10 THEN 'Od sześciu do dziesięciu'
WHEN COUNT(product_id) >10 THEN 'Powyżej dziesięciu'
END as Produkty
FROM order_items
GROUP BY order_id
ORDER BY order_id;

[collapse]

 

Zadanie 17.

Dla każdego klienta pokaż datę oraz numer pierwszego złożonego zamówienia, a także łączną ilość złożonych przez niego zamówień. Datę zamówienia sformatuj wg wzoru (screen).

Schemat: OE, tabela: Orders, Kolumny: customer_id, order_id, order_date, Wynik: 47 rows

p17

 

 

 

Rozwiązanie

SELECT customer_id||' ' as Customer, to_char(MIN(order_date), 'DD.MM.YYYY HH:MM:SS') as "First Order Date", MIN(order_id)as "First Order ID",
COUNT(order_id) "Total Orders"
FROM orders
GROUP BY customer_id
ORDER BY Customer;

Uwaga: Konkatencja przy customer_id w klauzuli SELECT ma na celu wyłącznie poprawienie czytelności wyniku; w innym wypadku kolumny customer_id i order_date zlewają się ze sobą i trudniej odczytać dane. Ciąg customer_id z “doklejoną” spacją (można dokleić też “nic” czyli ”) jest traktowany jako ciąg tekstowy i wyrównywany do lewej, w przeciwieństwie do typów liczbowych, które są wyrównywane do prawej.

[collapse]

Zadanie 15.

Policz, ile który klient złożył zamówień w każdym roku. Wybierz tych, którzy złożyli więcej niż jedno zamówienie. Zaznacz, który klient jest na którym miejscu względem ilości zamówień (funkcja dense_rank() połączona z funkcją okna).

Schemat: OE, Tabele: Customers, Orders, Kolumny: order_id, order_date, customer_id, Wynik: 23 rows

p15

 

 

 

 

 

 

Rozwiązanie

SELECT EXTRACT(YEAR from o.order_date) as "Year", customer_id as "Customer", COUNT(o.order_id) as "Orders",
DENSE_RANK() OVER(PARTITION BY EXTRACT(YEAR from o.order_date) ORDER BY COUNT(o.order_id) DESC) as "YrNum"
FROM orders o INNER JOIN customers c
USING(customer_id)
GROUP BY EXTRACT(YEAR from o.order_date), customer_id
HAVING COUNT(o.order_id) > 1
ORDER BY "Year", "YrNum";

[collapse]