Modül dersleri (1/4)
CTE: İLE çok adımlı sorgular
Gerçek sorgular büyüme eğilimindedir: üç JOIN, bir GROUP BY, bir alt sorgu,
başka bir alt sorgu… ve okunamaz hale geliyorlar. CTE'ler ("Ortak Tablo
İfadeler", WITH yan tümcesi), bir öğeye bir ad vermenize olanak tanır
ara adıma geçin ve bunu ana sorguda bir tablo gibi kullanın.
Temel sözdizimi
WITH nome_cte AS (
SELECT … -- query interna
)
SELECT … -- query principale, usa nome_cte come fosse una tabella
FROM nome_cte;Bir CTE yalnızca onu takip eden sorgu için geçerlidir: hayatta kalamaz infaz.
Örnek
En fazla harcama yapan 3 müşteriyi bulun (teslim edilen siparişlerin toplamı):
WITH total_spent AS (
SELECT o.customer_id,
SUM(oi.quantity * oi.unit_price) AS total
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
WHERE o.status = 'delivered'
GROUP BY o.customer_id
)
SELECT c.email,
s.total
FROM total_spent s
JOIN customers c ON c.id = s.customer_id
ORDER BY s.total DESC
LIMIT 3;İngilizce okuyun: "önce müşteri başına harcamayı hesaplayın; ardından şuna katılın:
Müşteriler ve ilk 3"'ü alın. CTE olmadan satır içi bir satıra ihtiyacınız olur
FROM alt sorgusu (yasal ama daha gürültülü).
Kademeli olarak birden fazla CTE
Virgüllerle ayrılmış birden çok CTE tanımlayabilirsiniz ve her biri başvuruda bulunabilir. öncekilere:
WITH total_spent AS (
SELECT customer_id, SUM(quantity * unit_price) AS total
FROM order_items oi
JOIN orders o ON oi.order_id = o.id
WHERE o.status = 'delivered'
GROUP BY customer_id
),
average AS (
SELECT AVG(total) AS total_average
FROM total_spent
)
SELECT c.email, s.total
FROM total_spent s
JOIN customers c ON c.id = s.customer_id
CROSS JOIN average
WHERE s.total > average.total_average
ORDER BY s.total DESC;CROSS JOIN average çünkü average her zaman tek bir satıra sahiptir:
Kartezyen çarpımı sonucun her satırına yalnızca total_average ekler.
CTE ve alt sorgu: ne zaman kullanılmalı, hangisi
CTE'ler şu durumlarda parlar:
- aynı alt sorgunun ana sorguda iki veya daha fazla kez kullanılması;
- yapıyı adlandırılmış adımlarda açık hale getirmek istiyorsunuz (kendi kendini belgeleme);
- bunlar özyinelemeli CTE'ler için önkoşuldur (
WITH RECURSIVE, Bu modüldeki bir sonraki ders).
Satır içi alt sorgu, yalnızca bir kez kullanılan bir adım için daha kısadır.
Deneyin
Her müşteri için teslim edilen siparişlerdeki toplam harcamayı (SUM(miktar * birim_fiyat)) hesaplayan 'total_spent' adlı bir CTE kullanın. Daha sonra ana sorguda en çok harcama yapan 3 kişinin e-postalarını ve toplamını gösterir. Toplamdan azalarak sıralayın, 3 ile sınırlıdır.
İpucu göster
CTE toplam miktarı * birim_fiyatı içinde. Ana sorguda kimlikteki müşterilere KATILIN.
3 denemeden sonra çözüm mevcut
Alıştırmayı gözden geçirin
Önceki alıştırmayla aynı 'total_spent' CTE. Ana sorguda, harcaması ortalama harcamanın üzerinde olan müşteriler için (en az bir teslim edilmiş siparişi olan tüm müşteriler için) e-postayı ve toplamı gösterir. Toplama göre azalan şekilde sıralayın.
İpucu göster
WHERE içindeki skaler alt sorgu: total_spent'ten AVG(total) SEÇİN.
3 denemeden sonra çözüm mevcut