نظّم استعلاماتك في خطوات مُسمّاة باستخدام WITH، واربط تعبيرات CTE معًا كخط أنابيب من التحويلات.
افتح هذا الدرس في Kodokonالاستعلام الفرعي المتداخل على ثلاثة مستويات يُقرأ من الداخل إلى الخارج: غير قابل للقراءة ويستحيل مراجعته بعد ستة أشهر. إن تعبير الجدول المشترك CTE (Common Table Expression، عبارة WITH) يقلب ترتيب القراءة: فأنت تُسمّي كل خطوة وسيطة تمامًا كما تُسمّي دالة، ويُقرأ الاستعلام من الأعلى إلى الأسفل. حمِّل مجموعة البيانات هذه في sqliteonline.com أو sqlite3.
CREATE TABLE payments (
id INTEGER PRIMARY KEY,
customer TEXT NOT NULL,
paid_at TEXT NOT NULL,
amount REAL NOT NULL
);
INSERT INTO payments (customer, paid_at, amount)
VALUES
('alice', '2026-01-10', 120.0),
('bruno', '2026-01-22', 80.0),
('alice', '2026-02-05', 60.0),
('chloe', '2026-02-18', 200.0),
('bruno', '2026-03-03', 40.0),
('alice', '2026-03-15', 90.0),
('chloe', '2026-03-28', 150.0),
('bruno', '2026-04-09', 300.0);الصياغة الأساسية: WITH name AS (SELECT ...) متبوعة بالاستعلام الرئيسي الذي يستخدم name كأنه جدول عادي. هنا، نحسب الإيراد الشهري باستخراج الشهر من التاريخ باستخدام substr (تواريخ SQLite هي نص بصيغة ISO 8601، وهو اختيار المحرّك لا معيار قياسي).
WITH monthly AS (
SELECT substr(paid_at, 1, 7) AS month,
SUM(amount) AS revenue
FROM payments
GROUP BY month
)
SELECT * FROM monthly ORDER BY month;تأتي القوة الحقيقية من الربط المتسلسل: عبارة WITH واحدة، وعدة تعبيرات CTE مفصولة بفواصل، يستطيع كل منها قراءة ما عُرّف قبله. أنت تبني خط أنابيب: تجمّع، وتحسب إحصائية، وتقارن. هنا، نبحث عن الأشهر التي يتجاوز إيرادها المتوسط الشهري (المتوقَّع: 2026-03 و2026-04، والمتوسط هو 260).
WITH monthly AS (
SELECT substr(paid_at, 1, 7) AS month,
SUM(amount) AS revenue
FROM payments
GROUP BY month
),
stats AS (
SELECT AVG(revenue) AS avg_revenue
FROM monthly
)
SELECT m.month, m.revenue,
ROUND(s.avg_revenue, 1) AS avg_all
FROM monthly AS m
CROSS JOIN stats AS s
WHERE m.revenue > s.avg_revenue
ORDER BY m.month;