الدرس 7 من 10

الأول في كل مجموعة

هدف الدرس

الترقيم بـ ROW_NUMBER والتقسيم بـ PARTITION BY

01

الشرح

يجمع GROUP BY كل مجموعة في صفّ واحد فتضيع تفاصيلها، أمّا دالة النافذة (window function) فتحسب على مجموعة من الصفوف وتُبقي كل صفّ في مكانه.

فالتعبير ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total DESC) يرقّم طلبات كل عميل وحده، لأنّ PARTITION BY يقسم الصفوف إلى مجموعات، وORDER BY يرتّب الصفوف داخل كل مجموعة، فيكون الرقم 1 لأكبر طلب عند كل عميل. وRANK() مثلها، إلا أنها تعطي الصفّين المتساويين الرقم نفسه.

ولا يمكنك أن تكتب دالة نافذة داخل WHERE، لأنّ النوافذ تُحسب بعد التصفية، ولذلك رقّم الصفوف داخل WITH، ثم اكتب WHERE rn = 1 في الاستعلام الخارجي.

02

المطلوب

اعرض أكبر طلب لكل عميل بالأعمدة name وplaced_on وtotal، مرتّبة من الأكبر إلى الأصغر.

الفحوص

5 فحوص
  1. الأعمدة name وplaced_on وtotal
  2. صفّ واحد لكل عميل له طلبات
  3. كل صفّ هو أكبر طلب لصاحبه
  4. التاريخ هو تاريخ ذلك الطلب
  5. مرتّبة من الأكبر إلى الأصغر
الجداول المتاحة في هذا الدرس
CREATE TABLE customers (
  id   INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  city TEXT NOT NULL
);

CREATE TABLE orders (
  id          INTEGER PRIMARY KEY,
  customer_id INTEGER REFERENCES customers(id),
  total       INTEGER NOT NULL,
  placed_on   TEXT    NOT NULL
);

INSERT INTO customers (id, name, city) VALUES
  (1, 'ليان', 'الرياض'),
  (2, 'خالد', 'جدة'),
  (3, 'ريم',  'الدمام'),
  (4, 'فهد',  'الرياض');

INSERT INTO orders (customer_id, total, placed_on) VALUES
  (1, 120, '2026-09-01'),
  (1,  80, '2026-09-12'),
  (2, 300, '2026-09-03'),
  (3,  45, '2026-09-20'),
  (2,  60, '2026-09-25');

INSERT INTO customers (id, name, city) VALUES (5, 'سارة', 'جدة');

CREATE TABLE products (
  id    INTEGER PRIMARY KEY,
  name  TEXT    NOT NULL,
  price INTEGER NOT NULL
);

CREATE TABLE order_items (
  id         INTEGER PRIMARY KEY,
  order_id   INTEGER REFERENCES orders(id),
  product_id INTEGER REFERENCES products(id),
  qty        INTEGER NOT NULL
);

INSERT INTO products (id, name, price) VALUES
  (1, 'دفتر',      15),
  (2, 'قلم',        5),
  (3, 'حقيبة',     90),
  (4, 'آلة حاسبة', 60),
  (5, 'مصباح',    100);

INSERT INTO order_items (order_id, product_id, qty) VALUES
  (1, 3, 1), (1, 1, 2),
  (2, 4, 1), (2, 2, 4),
  (3, 3, 2), (3, 4, 2),
  (4, 1, 3),
  (5, 1, 2), (5, 2, 6);
query.sql
المخرجاتSQLite (sql.js)

نحمّل بيئة SQLite الآن.

–/5

يبدأ الفحص حين تجهز البيئة.

تجد 5 فحوص في بطاقة «المطلوب».