الانتقال إلى المحتوى الرئيسي
الوحدة 7 · الدرس 1 من 425/57 في الدورة~12 min
دروس الوحدة (1/4)

CTE: استعلامات متعددة الخطوات باستخدام NOT

تميل الاستعلامات الحقيقية إلى النمو: ثلاثة JOINs، وGROUP BY، واستعلام فرعي، استعلام فرعي آخر... ويصبح غير قابل للقراءة. CTEs ("الجدول المشترك التعبيرات"، تتيح لك جملة WITH) إعطاء اسم إلى الخطوة المتوسطة واستخدمها كما لو كانت جدولاً في الاستعلام الرئيسي.

بناء الجملة الأساسي

SQL
WITH nome_cte AS (
  SELECT …    -- query interna
)
SELECT …      -- query principale, usa nome_cte come fosse una tabella
FROM   nome_cte;

CTE صالح ** فقط للاستعلام الذي يتبعه **: فهو غير موجود التنفيذ.

مثال

ابحث عن العملاء الثلاثة الذين أنفقوا أكبر قدر (مجموع الطلبات التي تم تسليمها):

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;

اقرأ باللغة الإنجليزية: "قم أولاً بحساب الإنفاق لكل عميل، ثم انضم إليه العملاء واتخاذ أعلى 3". بدون CTE ستحتاج إلى مضمنة استعلام فرعي في FROM (قانوني، ولكنه أكثر ضجيجًا).

CTEs متعددة في سلسلة

يمكنك تحديد عدة CTEs مفصولة بفواصل، ويمكن الرجوع إلى كل منها إلى السابقين:

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 لأن average يحتوي دائمًا على صف واحد: يُلحق المنتج الديكارتي total_average بكل صف من النتيجة.

CTE مقابل الاستعلام الفرعي: متى يتم استخدام أي منها

تتألق CTEs عندما:

  • يتم استخدام نفس الاستعلام الفرعي مرتين أو أكثر في الاستعلام الرئيسي؛
  • تريد جعل البنية واضحة في الخطوات المسماة (التوثيق الذاتي)؛
  • إنها الشرط الأساسي لـ CTEs العودية (WITH RECURSIVE، الدرس التالي في هذه الوحدة).

يكون الاستعلام الفرعي المضمن أكثر إيجازًا بالنسبة للخطوة المستخدمة مرة واحدة فقط.

جربه

تمرين#sql.m7.l1.e1
المحاولات: 0جارٍ التحميل…

استخدم CTE المسمى "total_spent" الذي يحسب، لكل عميل، إجمالي الإنفاق (SUM(quantity * Unit_price)) على الطلبات التي تم تسليمها. ثم في الاستعلام الرئيسي، قم بعرض البريد الإلكتروني والإجمالي لأعلى 3 منفقين. ترتيب تنازلي الإجمالي، والحد إلى 3.

جارٍ تحميل المحرر…
إظهار التلميح

داخل كمية مجموع CTE * سعر الوحدة. في الاستعلام الرئيسي انضم إلى العملاء على المعرف.

الحل متاح بعد 3 من المحاولات

تمرين المراجعة

تمرين#sql.m7.l1.e2
المحاولات: 0جارٍ التحميل…

نفس "total_spent" CTE مثل التمرين السابق. في الاستعلام الرئيسي، اعرض البريد الإلكتروني والإجمالي للعملاء الذين يتجاوز إنفاقهم متوسط ​​الإنفاق (عبر جميع العملاء الذين لديهم طلب واحد تم تسليمه على الأقل). ترتيب تنازلي المجموع.

جارٍ تحميل المحرر…
إظهار التلميح

استعلام فرعي عددي في المكان: SELECT AVG(total) FROM Total_spent.

الحل متاح بعد 3 من المحاولات