علی راشدی / مسیر یادگیریSQL · 20 HOURS
از مفاهیم تا تمرین واقعی

شروع SQL
در ۲۰ ساعت

یک برنامه‌ی کوتاه برای شروع یادگیری SQL در تحلیل داده؛ مفاهیم رو یاد بگیرید و از همون ابتدا با کوئری زدن تمرین کنید.

بعد از یادگیری هر بخش، می‌تونید در همین فایل کوئری بزنید و نتیجه رو ببینید. محیط تمرین در انتهای صفحه ↓

۰۱ / برنامه یادگیری

قدم به قدم

ساعت ۱ تا ۲

اولین کوئری‌ها

SELECT, WHERE, ORDER BY و محدود کردن تعداد ردیف‌های خروجی.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. سفارش‌های با مبلغ حداقل ۱۵۰ را از بیشترین مبلغ به کمترین مرتب کنید؛ فقط سه ردیف اول را نشان دهید.
  2. فقط ستون‌های شماره سفارش، تاریخ و مبلغ را در خروجی نگه دارید.
پاسخ پیشنهادی و بررسی خروجی
SELECT order_id, order_date, amount
FROM orders
WHERE amount >= 150
ORDER BY amount DESC, order_id
LIMIT 3;

خروجی: سفارش‌های ۱۰۵، ۱۰۳ و ۱۰۷. در SQLite و DuckDB از LIMIT استفاده کنید؛ SQL Server از TOP استفاده می‌کند.

ساعت ۳ تا ۴

خلاصه‌ کردن داده‌ها

COUNT, SUM, AVG, GROUP BY, HAVING

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. برای هر مشتری تعداد سفارش، مجموع و میانگین مبلغ را محاسبه کنید.
  2. با HAVING فقط مشتری‌هایی را نگه دارید که حداقل ۳ سفارش دارند.
پاسخ پیشنهادی و بررسی خروجی
SELECT customer_id, COUNT(*) AS order_count,
       SUM(amount) AS total_amount, AVG(amount) AS avg_amount
FROM orders
GROUP BY customer_id
HAVING COUNT(*) >= 3;

فقط مشتری ۱ باقی می‌ماند: ۴ سفارش، مجموع ۶۰۰ و میانگین ۱۵۰.

ساعت ۵ تا ۷

وصل کردن جدول‌ها

INNER JOIN و LEFT JOIN؛ بررسی کنید هر اتصال چه تغییری در تعداد ردیف‌ها ایجاد می‌کند.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. نام مشتری را کنار هر سفارش نمایش دهید؛ تعداد ردیف‌ها قبل و بعد از INNER JOIN را مقایسه کنید.
  2. با LEFT JOIN تعداد سفارش همه‌ی مشتری‌ها، حتی مشتری بدون سفارش را پیدا کنید.
پاسخ پیشنهادی و بررسی خروجی
SELECT c.customer_id, c.name, COUNT(o.order_id) AS order_count
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.name
ORDER BY c.customer_id;

تعداد سفارش‌ها: Ali = 4، Sara = 2، Reza = 2، Mina = 0. اینجا COUNT(*) برای مشتری بدون سفارش هم ۱ می‌شمارد؛ COUNT(o.order_id) لازم است.

ساعت ۸ تا ۹

شرط، مقدار خالی و تاریخ

کار با NULL، شرط‌گذاری با CASE WHEN و کار با تاریخ.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. مشتری با شهر نامشخص را با IS NULL پیدا کنید.
  2. سفارش‌های فوریه را انتخاب کنید و با CASE مبلغ حداقل ۲۰۰ را High و بقیه را Normal بنامید.
پاسخ پیشنهادی و بررسی خروجی
SELECT order_id,
       CASE WHEN amount >= 200 THEN 'High' ELSE 'Normal' END AS amount_group
FROM orders
WHERE order_date >= '2026-02-01'
  AND order_date < '2026-03-01'
ORDER BY order_id;

۱۰۴: Normal، ۱۰۵: High، ۱۰۶: Normal. تاریخ‌ها در دیتاست متنی و با قالب ثابت YYYY-MM-DD هستند. توابع تاریخ بین دیتابیس‌ها فرق می‌کنند.

ساعت ۱۰ تا ۱۲

شکستن مسئله به چند مرحله

یادگیری Subquery و CTE برای خواناتر کردن کوئری‌ها.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. سفارش‌های گران‌تر از میانگین کل را با یک Subquery پیدا کنید.
  2. با CTE مجموع خرید هر مشتری را بسازید و مشتری‌های با مجموع خرید بیش از ۳۰۰ را انتخاب کنید.
پاسخ پیشنهادی و بررسی خروجی
WITH customer_sales AS (
  SELECT customer_id, SUM(amount) AS total_amount
  FROM orders
  GROUP BY customer_id
)
SELECT * FROM customer_sales WHERE total_amount > 300;

مشتری ۱ با مجموع ۶۰۰ و مشتری ۳ با مجموع ۳۲۰. برای تمرین اول: WHERE amount > (SELECT AVG(amount) FROM orders).

ساعت ۱۳ تا ۱۵

Window Functions

آشنایی با ROW_NUMBER, RANK, LAG, SUM OVER.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. با ROW_NUMBER سفارش‌های هر مشتری را شماره‌گذاری و با LAG مبلغ سفارش قبلی او را پیدا کنید.
  2. مجموع تجمعی خرید هر مشتری را بسازید؛ بعد با RANK همه‌ی سفارش‌ها را بر اساس مبلغ رتبه‌بندی کنید و تفاوت رتبه با شماره ردیف را ببینید.
پاسخ پیشنهادی و بررسی خروجی
SELECT customer_id, order_id, amount,
 ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date, order_id) AS rn,
 LAG(amount) OVER (PARTITION BY customer_id ORDER BY order_date, order_id) AS prev_amount,
 SUM(amount) OVER (PARTITION BY customer_id ORDER BY order_date, order_id
  ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total,
 RANK() OVER (ORDER BY amount DESC) AS amount_rank
FROM orders
ORDER BY customer_id, order_date, order_id;

برای مشتری ۱، مجموع تجمعی باید ۱۰۰، ۲۵۰، ۵۵۰ و ۶۰۰ شود. LAG اولین سفارش NULL است؛ سفارش‌های هم‌مبلغ در RANK رتبه‌ی یکسان می‌گیرند.

ساعت ۱۶ تا ۱۸

حل سؤال

از سؤال‌های ساده‌تر مجموعه‌ی SQL 50 در LeetCode شروع کنید.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. در SQL 50 این سه سؤال را حل کنید: Recyclable and Low Fat Products، Customer Who Visited but Did Not Make Any Transactions و Customers Who Bought All Products.
  2. قبل از دیدن پاسخ، خروجی مورد انتظار و دلیل انتخاب JOIN یا GROUP BY را بنویسید.
معیار بررسی تمرین

معیار پیشرفت: کوئری فقط روی نمونه کار نکند؛ NULL، ردیف تکراری و مشتری بدون سفارش را هم در نظر بگیرید. ساختار جدول هر سؤال با دیتاست این فایل متفاوت است.

ساعت ۱۹ تا ۲۰

تمرین با دیتاست

با دیتاست آماده‌ی همین صفحه به سؤال‌هایی مثل مشتری‌های پرتکرار، فروش ماهانه و سهم هر دسته پاسخ دهید.

اول از اینجا یاد بگیرید

آموزش‌های این بخش رو باز کنید؛ بعد تمرین پایین رو انجام بدید.

تمرین این بخش
  1. با دیتاست این فایل، فروش ماهانه، مشتری‌های پرتکرار و سهم مبلغ فروش هر دسته را محاسبه کنید.
  2. برای هر خروجی یک جمله نتیجه بنویسید؛ مجموع فروش را با جمع فروش دسته‌ها کنترل کنید.
پاسخ پیشنهادی و بررسی خروجی
SELECT SUBSTR(order_date, 1, 7) AS month, SUM(amount) AS sales
FROM orders
GROUP BY SUBSTR(order_date, 1, 7) ORDER BY month;

SELECT category, SUM(amount) AS sales,
 ROUND(100.0 * SUM(amount) / (SELECT SUM(amount) FROM orders), 2) AS share_pct
FROM orders GROUP BY category;

فروش ماهانه: ژانویه ۴۵۰، فوریه ۵۰۰، مارس ۲۵۰. مجموع ۱۲۰۰؛ Food حدود ۷۰٫۸۳٪ و Cafe حدود ۲۹٫۱۷٪. مشتری پرتکرار را در این تمرین با حداقل ۳ سفارش تعریف کنید.

زمان‌بندی تقریبی است؛ مخصوصاً JOIN و Window Function ممکن است به تمرین بیشتری نیاز داشته باشند. ۲۰ ساعت نقطه‌ی شروع است و تضمین تسلط نیست.
۰۲ / منابع

برای شروع و تمرین

محیط تمرین / بدون نصب

همین‌جا کوئری بزنید

دیتاست آماده است: ۴ مشتری و ۸ سفارش با مبلغ‌های فرضی. کوئری را بنویسید و «اجرا» را بزنید. برای شروع می‌توانید یکی از نمونه‌ها را انتخاب کنید.

customers: customer_id, name, city
orders: order_id, customer_id, order_date, amount, category
در حال آماده‌سازی…

میان‌بر اجرا: Ctrl + Enter. تمرین‌ها و پاسخ‌ها پایین همین صفحه‌اند؛ با دکمه‌ی «باز کردن در محیط تمرین» منتقلشان کنید.

درباره‌ی محیط و دیتاست

موتور این محیط SQLite است و داخل فایل قرار دارد؛ برای اجرای کوئری به اینترنت نیاز ندارید. منابع آموزشی با اینترنت باز می‌شوند. تاریخ‌ها به‌صورت متن YYYY-MM-DD ذخیره شده‌اند. فقط کوئری‌های خواندنی اجرا می‌شوند و دیتاست برای هر اجرا از نو آماده می‌شود؛ ساخت و تغییر جدول بخشی از این تمرین نیست. حداکثر ۵۰۰ ردیف از هر خروجی نمایش داده می‌شود. کد اصلی موتور: sql.js (MIT).

فایل را دانلود کنید و در مرورگر باز کنید؛ بعضی پیش‌نمایش‌های پیام‌رسان اجرای JavaScript را غیرفعال می‌کنند.