إجراء Pivot باستخدام التجميع الشرطي
نمط محمول يعتمد على وضع CASE داخل SUM لتحويل الصفوف إلى أعمدة
إجراء Pivot باستخدام التجميع الشرطي درس مجاني في Coding Interview Prep على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Coding Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
إعداد المقابلة
إحدى أكثر مهام مقابلات إعداد التقارير شيوعًا هي: تحويل الصفوف إلى أعمدة. لديك جدول طويل مثل sales(region, quarter, amount)، ويريد المحاور تقريرًا عريضًا يحتوي على عمود لكل ربع.
الإجابة القابلة للنقل والمستقلة عن لهجة SQL التي يريدون سماعها هي التجميع الشرطي: تعبير CASE موضوع داخل دالة تجميع مثل SUM. أتقن هذا النمط، وستتمكن من تنفيذ pivot في أي قاعدة بيانات، حتى تلك التي لا تحتوي على الكلمة المفتاحية PIVOT.
الشكل الطويل مقابل العريض
قبل تنفيذ pivot، سمِّ الشكلين. يخزّن الشكل الطويل حقيقة واحدة في كل صف: يكون لكل زوج من المنطقة والربع صف مستقل. أما الشكل العريض فيوزّع الفئة على أعمدة.
- الطويل: سهل الإدراج، لكنه صعب القراءة جنبًا إلى جنب.
- العريض: مناسب جدًا لتقرير موجّه إلى المستخدم.
يحوّل pivot الشكل الطويل إلى شكل عريض. ويحب المحاورون هذا السؤال لأنه يختبر فهمك للتجميع، لا للصياغة فقط.
-- Long form (the input)
region | quarter | amount
-------+---------+-------
East | Q1 | 100
East | Q2 | 150
West | Q1 | 200
West | Q2 | 250النمط الأساسي
الحيلة هي: لكل عمود ناتج، اكتب CASE يعيد القيمة عندما يطابق الصف ذلك العمود، ويعيد NULL بخلاف ذلك. ثم غلّفه داخل دالة تجميع حتى تُختزل المجموعة إلى صف واحد لكل مفتاح.
اقرأه هكذا: اجمع amount، ولكن لصفوف Q1 فقط. وبما أن SUM يتجاهل NULL، فلن تساهم الصفوف غير المطابقة بأي قيمة.
SELECT
region,
SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2
FROM sales
GROUP BY region;سبب تجاهل SUM للقيم NULL
يعمل هذا النمط بسبب حقيقة واحدة سيسألك المحاورون عنها: دوال التجميع تتخطى القيم NULL. يعيد CASE الذي لا يحتوي على ELSE القيمة NULL عندما لا يطابق أي فرع، ولذلك لا يجمع SUM(CASE WHEN ... THEN amount END) إلا الصفوف التي اخترتها.
ولو كتبت ELSE 0 بدلًا من ذلك، فسيعمل أيضًا مع SUM (إذ إن إضافة الصفر لا تغيّر شيئًا)، لكنه سيفسد سلوك AVG وMIN وCOUNT.
-- Both produce the same SUM result:
SUM(CASE WHEN quarter = 'Q1' THEN amount END)
SUM(CASE WHEN quarter = 'Q1' THEN amount ELSE 0 END)مثال تطبيقي: تقرير ربع سنوي
فيما يلي الاستعلام الكامل المُطبَّق على البيانات النموذجية. تصبح كل منطقة صفًا واحدًا، ويصبح كل ربع عمودًا واحدًا.
إن GROUP BY region هو ما يختزل صفوف الإدخال الأربعة إلى صفَّي إخراج. وبدونه، ستحصل على صف واحد لكل صف إدخال، مع معظم القيم NULL.
SELECT
region,
SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2
FROM sales
GROUP BY region;
-- Result:
-- region | q1 | q2
-- East | 100 | 150
-- West | 200 | 250اختيار دالة التجميع المناسبة
يجب أن تتوافق دالة التجميع التي تضع CASE داخلها مع السؤال:
SUMعندما تجمع كل خلية قيمًا.MAXأوMINعندما يحتوي كل زوج من المنطقة والربع على قيمة واحدة بالضبط، وتريد عرضها فحسب.COUNTعندما تعدّ كل خلية الصفوف المطابقة.
غالبًا ما يطرح المحاوِرون صيغة COUNT: كم عدد الطلبات لكل حالة في كل شهر؟
SELECT
month,
COUNT(CASE WHEN status = 'shipped' THEN 1 END) AS shipped,
COUNT(CASE WHEN status = 'cancelled' THEN 1 END) AS cancelled
FROM orders
GROUP BY month;استخدام MAX للخلايا ذات القيمة الواحدة
عندما يحتوي كل زوج من المفتاح والفئة على قيمة واحدة (أي جدول تقاطعي فعلي، وليس إجماليًا)، استخدم MAX أو MIN. فكلاهما يعيد القيمة الوحيدة غير NULL ويتجاهل قيم NULL الناتجة عن الفروع غير المطابقة.
يُعد هذا الخيار الآمن عند إعادة تشكيل السمات بدلًا من جمع الأموال، مثل تحويل جدول إعدادات من نوع مفتاح/قيمة إلى صف واحد لكل كيان.
-- Turn key/value rows into one wide row per user
SELECT
user_id,
MAX(CASE WHEN attr = 'city' THEN value END) AS city,
MAX(CASE WHEN attr = 'plan' THEN value END) AS plan
FROM user_attributes
GROUP BY user_id;التعامل مع خلايا الإخراج التي قيمتها NULL
إذا لم تُسجّل منطقة ما أي مبيعات في الربع الثاني، فستظهر خلية q2 فيها القيمة NULL. قد يطلب منك المحاوِرون عرض 0 بدلًا منها. لفّ دالة التجميع بأكملها داخل COALESCE.
ضع COALESCE خارج دالة التجميع، لا داخل CASE، كي تستبدل القيمة فقط عندما لا يحتوي التجميع بأكمله على صفوف مطابقة.
SELECT
region,
COALESCE(SUM(CASE WHEN quarter = 'Q1' THEN amount END), 0) AS q1,
COALESCE(SUM(CASE WHEN quarter = 'Q2' THEN amount END), 0) AS q2
FROM sales
GROUP BY region;إضافة عمود الإجمالي الكلي
من الأسئلة الشائعة اللاحقة: إضافة إجمالي عبر جميع الأعمدة التي جرى تدويرها. لا تحتاج إلى جمع الأعمدة بأسمائها؛ إذ يمنحك SUM(amount) العادي على المجموعة نفسها إجمالي الصف، لأنه يتجاهل ترشيح CASE تمامًا.
يوضح ذلك للمحاوِر أنك تدرك أن كل دالة تجميع في SELECT تُحسب بصورة مستقلة على المجموعة نفسها.
SELECT
region,
SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2,
SUM(amount) AS total
FROM sales
GROUP BY region;اختصار التجميع المصفّى
يدعم PostgreSQL ومعيار SQL الصيغة FILTER (WHERE ...)، وهي طريقة أنظف لكتابة التجميع الشرطي. فقراءتها أوضح وتتجنب الصياغة النمطية الخاصة بـ CASE.
اذكر هذه الصيغة في المقابلة لإظهار اتساع معرفتك، لكن تذكّر أن MySQL وSQL Server لا يدعمانها، ولذلك تظل CASE هي الإجابة القابلة للنقل بين الأنظمة.
-- Postgres / standard SQL
SELECT
region,
SUM(amount) FILTER (WHERE quarter = 'Q1') AS q1,
SUM(amount) FILTER (WHERE quarter = 'Q2') AS q2
FROM sales
GROUP BY region;القيد الرئيسي
هناك قيد واحد في التجميع الشرطي سيصرّ المحاوِرون على مناقشته: يجب أن تُدرج كل عمود إخراج يدويًا. فإذا لم تكن الأرباع أو الفئات معروفة مسبقًا، فلن يتمكن هذا الاستعلام الثابت من التكيّف.
تُسمّى هذه المشكلة التدوير الديناميكي، وتتطلب SQL مُولَّدًا. أما عند وجود مجموعة ثابتة ومعروفة من الفئات، فالتجميع الشرطي هو الخيار الأنظف والأكثر قابلية للنقل.
اختبار سريع
اختبر مدى استيعابك لنمط التجميع الشرطي.
مراجعة
التجميع الشرطي هو أسلوب التدوير القابل للنقل الذي يقبله كل محاوِر:
- استخدم
CASEواحدًا لكل عمود إخراج، ولفّه داخل دالة تجميع. - استخدم
SUMللإجماليات، وMAX/MINللخلايا ذات القيمة الواحدة، وCOUNTللعدّ. - يعمل ذلك لأن دوال التجميع تتجاهل قيمة
NULLالناتجة عن الفروع غير المطابقة. - استخدم
COALESCEلتحويل الخلايا الفارغة إلى 0. - القيد: يجب تضمين الأعمدة في الاستعلام صراحةً، مما يقودنا بعد ذلك إلى التدويرات الديناميكية.
الأسئلة الشائعة
هل درس «إجراء Pivot باستخدام التجميع الشرطي» مجاني؟
نعم — نص درس «إجراء Pivot باستخدام التجميع الشرطي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Coding Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «إجراء Pivot باستخدام التجميع الشرطي»؟
نمط محمول يعتمد على وضع CASE داخل SUM لتحويل الصفوف إلى أعمدة تتمرن على Coding Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Coding Interview Prep؟
لا تُشترط خبرة سابقة. Coding Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «إجراء Pivot باستخدام التجميع الشرطي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Coding Interview Prep هذا؟
نعم. كل درس في Coding Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- إجراء Pivot باستخدام التجميع الشرطي
- صياغة PIVOT وCrosstab الخاصة بالمورّد
- تحويل الأعمدة إلى صفوف
- عمليات Pivot ديناميكية بأعمدة غير معروفة