Ana içeriğe geç
Modül 7 · Ders 1 ders 4Kurstaki 25/57~12 min
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

SQL
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ı):

SQL
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:

SQL
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

Egzersiz#sql.m7.l1.e1
Denemeler: 0Yükleniyor…

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.

Düzenleyici yükleniyor…
İ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

Egzersiz#sql.m7.l1.e2
Denemeler: 0Yükleniyor…

Ö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.

Düzenleyici yükleniyor…
İpucu göster

WHERE içindeki skaler alt sorgu: total_spent'ten AVG(total) SEÇİN.

3 denemeden sonra çözüm mevcut