در SQL، دستورها به چند دسته اصلی تقسیم میشوند:
| دسته | توضیح |
|---|---|
| DDL | تعریف ساختار داده (مثل CREATE, ALTER, DROP) |
| DML | دستکاری داده (مثل INSERT, UPDATE, DELETE) |
| DQL | پرسوجو از دادهها (مانند SELECT) |
| DCL | کنترل دسترسی (مثل GRANT, REVOKE) |
| TCL | کنترل تراکنشها (مثل COMMIT, ROLLBACK) |
✅ DQL (Data Query Language) وظیفهی واکشی و نمایش دادهها را بر عهده دارد.
در واقع، همه چیز در DQL حول محور دستور SELECT میچرخد .
ساختار کلی دستور SELECT به صورت زیر است:
SELECT [DISTINCT] column_list
FROM table_name
[WHERE condition]
[GROUP BY column_list]
[HAVING group_condition]
[ORDER BY column_list [ASC|DESC]]
[LIMIT n OFFSET m];
بیایید هر بخش را بررسی کنیم 👇
با SELECT مشخص میکنیم کدام ستونها را میخواهیم ببینیم:
SELECT first_name, last_name
FROM customers;
🔹 برای انتخاب همهی ستونها:
SELECT * FROM customers;
SELECT DISTINCT country
FROM customers;
🔹 نتیجه فقط کشورهای یکتا را نمایش میدهد.
بخش FROM مشخص میکند داده از کدام جدول یا ویو باید خوانده شود.
مثلاً:
SELECT *
FROM orders;
برای محدود کردن دادهها از شرط WHERE استفاده میکنیم:
SELECT *
FROM customers
WHERE country = 'Germany';
🔹 میتوان از عملگرها استفاده کرد:
=, <>, <, >, <=, >=AND, OR, NOTLIKE, ILIKEIN, NOT INBETWEEN ... AND ...برای محاسبات تجمیعی (مثل میانگین، جمع، تعداد) استفاده میشود:
SELECT country, COUNT(*) AS customer_count
FROM customers
GROUP BY country;
برخلاف WHERE که روی ردیفها اعمال میشود، HAVING روی گروهها اعمال میشود:
SELECT country, COUNT(*) AS customer_count
FROM customers
GROUP BY country
HAVING COUNT(*) > 5;
SELECT first_name, country
FROM customers
ORDER BY country ASC, first_name DESC;
🔹 ASC = صعودی (پیشفرض)
🔹 DESC = نزولی
برای مثال، فقط ۵ ردیف اول را ببینیم:
SELECT *
FROM customers
LIMIT 5;
و برای پرش از چند ردیف اول:
SELECT *
FROM customers
LIMIT 5 OFFSET 10;
یکی از مهمترین مفاهیم در DQL ترتیب واقعی اجرای بخشهای مختلف است.
SQL از بالا به پایین نوشته میشود، ولی از نظر اجرا به شکل زیر عمل میکند:
| مرحله – ترتیب اجرا | بخش | توضیح |
|---|---|---|
| ۱ | FROM | انتخاب منبع داده |
| ۲ | WHERE | فیلتر کردن ردیفها |
| ۳ | GROUP BY | گروهبندی ردیفها |
| ۴ | HAVING | فیلتر کردن گروهها |
| ۵ | SELECT | انتخاب ستونها و محاسبه توابع |
| ۶ | DISTINCT | حذف تکراریها |
| ۷ | ORDER BY | مرتبسازی |
| ۸ | LIMIT / OFFSET | محدودسازی نتایج |
📘 یعنی اگر در SELECT به ستونی اشاره کنید که هنوز در GROUP BY وجود ندارد، خطا میگیرید.
SELECT
country,
COUNT(*) AS customer_count,
AVG(orders_total) AS avg_order
FROM customers
WHERE country IN ('USA', 'Germany', 'UK')
GROUP BY country
HAVING COUNT(*) > 5
ORDER BY avg_order DESC
LIMIT 3;
✅ نتیجه: بین سه کشور آلمان، آمریکا و انگلیس، تعداد مشتریان آن کشور با میانگین سفارشات هر مشتری را بر میگرداند به ترتیب میانگین سفارش (از بزرگ به کوچک)
Northwind یک دیتابیس نمونه است که شبیهسازی یک شرکت بازرگانی صادرات/واردات مواد غذایی را انجام میدهد و در آن اطلاعاتی درباره مشتریان، سفارشها، محصولات، تأمینکنندگان و کارمندان ذخیره شده است.
در این جلسه، برای آشنایی با DQL از دیتابیس Northwind استفاده میکنیم و بهتر است ابتدا یک نگاه کلی به آن بیندازیم.

| جدول | توضیح کلی | فیلدهای مهم | توضیح فیلدها |
|---|---|---|---|
| customers | اطلاعات مشتریان شرکت | customer_id, company_name, contact_name, country, city | شامل اطلاعات تماس و موقعیت جغرافیایی مشتریان |
| orders | سفارشهایی که مشتریان ثبت کردهاند | order_id, customer_id, employee_id, order_date, ship_country, freight | هر ردیف یک سفارش است؛ با شناسه مشتری و کارمند مرتبط میشود. منظور از freight در این جدول، هزینه ارسال است. |
| order_details | جزئیات اقلام هر سفارش | order_id, product_id, unit_price, quantity, discount | اقلامی که در هر سفارش وجود دارند؛ معمولاً برای محاسبه جمع سفارش استفاده میشود |
| products | اطلاعات کالاها و محصولات فروختهشده | product_id, product_name, supplier_id, category_id, unit_price, units_in_stock | اطلاعات محصولات و قیمتها |
| suppliers | اطلاعات تأمینکنندگان کالا | supplier_id, company_name, contact_name, country | از چه شرکتهایی محصولات خریداری میشود |
| categories | دستهبندی محصولات | category_id, category_name, description | هر محصول به یک دسته مربوط است (مثل نوشیدنی، لبنیات و…) |
| employees | اطلاعات کارمندان شرکت | employee_id, first_name, last_name, title, reports_to, hire_date | کارمندانی که سفارشها را مدیریت میکنند |
| shippers | اطلاعات شرکتهای حملونقل | shipper_id, company_name, phone | شرکتهایی که وظیفه ارسال کالا را دارند |
| regions | مناطق جغرافیایی | region_id, region_description | برای دستهبندی نواحی مکانی مورد استفاده است |
| territories | نواحی فروش | territory_id, territory_description, region_id | نواحی خاصی که به هر منطقه مرتبط هستند |
| employee_territories | رابطه بین کارمندان و نواحی فروش | employee_id, territory_id | هر کارمند ممکن است چند ناحیه فروش داشته باشد |
| رابطه | نوع ارتباط | توضیح |
|---|---|---|
customers ↔ orders | یک به چند | هر مشتری چند سفارش دارد |
orders ↔ order_details | یک به چند | هر سفارش شامل چند محصول است |
products ↔ order_details | یک به چند | هر محصول ممکن است در چند سفارش باشد |
suppliers ↔ products | یک به چند | هر تأمینکننده چند محصول ارائه میدهد |
categories ↔ products | یک به چند | هر دسته شامل چند محصول است |
employees ↔ orders | یک به چند | هر سفارش توسط یک کارمند مدیریت میشود |
shippers ↔ orders | یک به چند | هر سفارش با یک شرکت حملونقل ارسال میشود |
۱️⃣ نمایش لیست مشتریان آلمانی:
SELECT customer_id, company_name, city
FROM customers
WHERE country = 'Germany';
۲️⃣ نمایش تعداد سفارشهای هر مشتری:
SELECT customer_id, COUNT(*) AS total_orders
FROM orders
GROUP BY customer_id
ORDER BY total_orders DESC;
۳️⃣ محاسبه مبلغ کل هر سفارش:
SELECT
o.order_id,
SUM(od.unit_price * od.quantity * (1 - od.discount)) AS total_amount
FROM orders o
JOIN order_details od ON o.order_id = od.order_id
GROUP BY o.order_id;
۴️⃣ تعداد محصولات هر دسته:
SELECT c.category_name, COUNT(p.product_id) AS total_products
FROM categories c
JOIN products p ON c.category_id = p.category_id
GROUP BY c.category_name;
customers, orders, order_details, products, و categories خواهد بود.AS برای نامگذاری ستونهای خروجی که نتیجه اعمال یک تابع یا یک عبارت محاسباتی هستند، استفاده کنید.ORDER BY دارید، میتوانید از نام مستعار (alias) که در قسمت ابتدایی دستور Select اختصاص دادهاید، استفاده کنید.