عندما يكون الترتيب مبنيًا على إجمالي طلبات العميل، يجب حساب هذا الإجمالي قبل ترتيب العملاء. تطبيق دالة الرتبة مباشرة على صفوف الطلبات يرتب الطلبات المفردة، وقد يجعل العميل يظهر عدة مرات. الحل الواضح هو تحويل البيانات أولًا إلى صف واحد لكل عميل.
نستخدم CTE لحساب المجموع بحسب البلد والعميل، ثم نستخدم CTE ثانية لحساب DENSE_RANK() على الإجماليات داخل كل بلد. إذا كان المطلوب جميع العملاء ضمن أعلى مستويين مختلفين من الإجمالي، نختار الرتب الأولى والثانية مع الاحتفاظ بالتعادل.
مثال
WITH orders AS (
SELECT 1 AS id, 10 AS customer_id, 'JO' AS country, 300 AS amount
UNION ALL SELECT 2, 10, 'JO', 400
UNION ALL SELECT 3, 20, 'JO', 600
), totals AS (
SELECT country, customer_id, SUM(amount) AS total_amount
FROM orders
GROUP BY country, customer_id
), ranked AS (
SELECT country, customer_id, total_amount,
DENSE_RANK() OVER (
PARTITION BY country ORDER BY total_amount DESC
) AS dr
FROM totals
)
SELECT country, customer_id, total_amount
FROM ranked
WHERE dr <= 2
ORDER BY country, dr, customer_id;
يفترض المثال أن كل طلب يحمل بلد العميل المعتمد لهذا التقرير. ترتيب المراحل مهم: التجميع يحدد وحدة المقارنة، والتقسيم يحدد نطاق المنافسة، ودالة الرتبة تحدد كيفية التعامل مع تساوي الإجماليات، ثم تختار التصفية المستويات المطلوبة.
باختصار: اجمع الطلبات لكل عميل أولًا، ثم رتّب الإجماليات داخل كل بلد، ثم صفِّ الرتب في مستوى خارجي.
هل تريد تعلّم SQL خطوة بخطوة مع تمارين عملية؟ تابع مسار SQL من الأساسيات للاحتراف.