SQL – klauzula WITH oraz subqueries

Subqueries to podzapytania umieszczone w głównym zapytaniu SQL (tzn w głównym zapytaniu zagnieżdżamy pełne zapytania select – from). Zazwyczaj nie są one konieczne i można podobne efekty uzyskać wykonując JOIN-y do danych tabel z podzapytań.

SUBQUERIES

Podzapytania możemy stosować w klauzuli WHERE:

SELECT * FROM sales WHERE product_id IN (SELECT product_id FROM products WHERE color=”RED”)

Można też dodać kolejne poziomy zagnieżdżeń:

SELECT * FROM sales WHERE product_id IN (SELECT product_id FROM products WHERE color=”RED” AND category IN (SELECT category FROM categories WHERE category_id = 4))

Podzapytania możemy stosować też w klauzuli JOIN:

SELECT * FROM sales s LEFT JOIN

(SELECT p.product_id, p.type FROM products p INNER JOIN product_category pc on pc.product_id=p.id and pc.type=’OTHER’) o

on p.product_id = s.product_id

A także przed klauzulą FROM:

SELECT name, surname, price, (SELECT avg(price) FROM clients) as avg_price FROM clients

Lub w bardziej rozbudowanej opcji:

SELECT name, surname, (SELECT type FROM client_details cd WHERE cd.client_id=c.id) as type

FROM clients – tutaj kiedy odwołujemy się do innej tabeli niż w głównym from musimy zawrzeć klauzulę where z połączeniem.

Klauzula WITH

Jest niezwykle intuicyjnym sposobem pisania zapytań, czytelnym dla innych użytkowników, o dużej wydajności, szczególnie podczas pisania złożonych zapytań. Umożliwia unikalne tworzenie „workowych” tabelek w jednym zapytaniu z możliwością dowolnego odwoływania się do nich. Przejmując kod po innym programiście, można z łatwością odtworzyć jego tok myślenia 😊

with t1 as (

SELECT * FROM sales s WHERE order_date > ‘2024-01-01’ ),

t2 as (

SELECT * FROM products p LEFT JOIN product_details pd ON p.product_key=pd.product_key

WHERE p.product_id in (1,6) and pd.details IS NOT NULL ),

t3 as ( SELECT * FROM additional_orders a INNER JOIN t1 ON a.client_id=s.client_id AND a.order_date>t1.order_date)

SELECT * FROM t3 LEFT JOIN t2 ON t3.client_id=p.client_id

Porównanie obydwu technik

WITH:

– wysoka czytelność kodu, łatwe przekazywanie innym koderom

– używane głównie dla złożonych zapytań, dużych zbiorów danych

– można dowolnie odwoływać się do utworzonych tabelek w obrębie jednego zapytania

– zajmują miejsce w pamięci (tworzenie tzw workowej tabeli dla zapytania)

SUBQUERIES:

– nie zajmują miejsca w pamięci

– bardziej wydajne i częściej używane dla mniej złożonych zapytań i mniejszych zbiorów danych