بخش اول: ورود به جهان قدرتمند PostgreSQL
بخش دوم: جادوی جستجو و کوئری‌نویسی
بخش سوم: بهینه‌سازی و ساختارهای پیشرفته
بخش چهارم: امنیت، پشتیبانی، عملکرد و نگه‌داری
کارگاه‌ها و مثال‌های کاربردی

تجمیع و گروه‌بندی داده‌ها (Aggregation & Grouping)

در دنیای واقعی، ما معمولاً فقط به مشاهده‌ی تک‌تک ردیف‌های داده علاقه‌مند نیستیم،
بلکه می‌خواهیم الگوها، جمع‌ها، میانگین‌ها و خلاصه‌های آماری را از میان آن‌ها استخراج کنیم.

برای مثال، تصور کنید در فروشگاه Northwind می‌خواهیم بدانیم:

  • هر برند در هر روز چقدر فروش داشته است؟
  • میانگین هزینه‌ی حمل در هر کشور چقدر است؟
  • کدام کارمند بیشترین تعداد سفارش را ثبت کرده است؟

در چنین موقعیت‌هایی لازم است ابتدا داده‌ها را بر اساس یک یا چند ویژگی گروه‌بندی کنیم (مثلاً بر اساس کشور یا برند)،
و سپس با کمک توابع تجمیعی (Aggregate Functions) روی هر گروه محاسباتی مانند جمع، میانگین یا شمارش انجام دهیم.

به عبارت دیگر:

«گروه‌بندی یعنی سازمان‌دهی داده‌ها در دسته‌های منطقی و توابع تجمیعی ابزار ما برای تحلیل و استخراج خلاصه‌ی اطلاعات از هر دسته هستند.»

در PostgreSQL، این کار با ترکیب دستورهای GROUP BY و توابعی مانند SUM(), AVG(), COUNT(), MIN(), MAX() انجام می‌شود.
در ادامه یاد می‌گیریم چگونه این قابلیت‌ها را به‌صورت گام‌به‌گام در کوئری‌های واقعی پیاده کنیم.

در پایان این بخش، شما قادر خواهید بود:

  • از توابع تجمیعی مانند COUNT, SUM, AVG, MIN, MAX استفاده کنید.
  • داده‌ها را با GROUP BY در گروه‌های مختلف دسته‌بندی کنید.
  • با استفاده از HAVING روی نتایج تجمیعی فیلتر اعمال کنید.
  • از گروه‌بندی موقعیتی (GROUP BY 1, 2) برای نوشتن سریع‌تر استفاده کنید.
  • رفتار توابع تجمیعی با مقادیر NULL را درک کنید.
  • از ترکیب CASE و توابع تجمیعی برای گزارش‌های شرطی استفاده کنید.

🔹 آشنایی با توابع تجمیعی (Aggregate Functions)

توابع تجمیعی چندین ردیف را در یک مقدار خلاصه‌شده ترکیب می‌کنند.

تابعتوضیح
COUNT()شمارش تعداد ردیف‌ها
SUM()مجموع مقادیر عددی
AVG()میانگین مقادیر
MIN()کمترین مقدار
MAX()بیشترین مقدار
مثال:
SELECT 
    COUNT(*)           AS total_orders,
    SUM(freight)       AS total_freight,
    AVG(freight)       AS avg_freight,
    MIN(freight)       AS min_freight,
    MAX(freight)       AS max_freight
FROM orders;
تمرین‌ها:
  1. تعداد کل سفارش‌ها را بیابید.
  2. میانگین هزینه حمل (freight) را محاسبه کنید.
  3. کمترین و بیشترین مقدار freight را بیابید.

🔹 گروه‌بندی نتایج با GROUP BY

GROUP BY ردیف‌هایی که مقدار مشترک در یک ستون دارند را در گروه‌هایی دسته‌بندی می‌کند و توابع تجمیعی روی هر گروه اعمال می‌شوند.

SELECT 
    ship_country, 
    COUNT(*) AS total_orders
FROM orders
GROUP BY ship_country;
مثال – میانگین هزینه حمل در هر کشور:
SELECT 
    ship_country, 
    ROUND(AVG(freight), 2) AS avg_freight
FROM orders
GROUP BY ship_country
ORDER BY avg_freight DESC;
تمرین‌ها:
  • تعداد سفارش‌های هر کارمند (employee_id) را بیابید.
  • مجموع کل هزینه‌ی حمل در هر کشور را محاسبه کنید.

🔹 گروه‌بندی بر اساس چند ستون

می‌توانیم بیش از یک ستون را در GROUP BY بیاوریم تا ترکیب آن‌ها به‌عنوان کلید گروه در نظر گرفته شود:

SELECT 
    ship_country, 
    ship_city, 
    COUNT(*) AS num_orders
FROM orders
GROUP BY ship_country, ship_city
ORDER BY ship_country;

💡 هر ترکیب یکتای (کشور، شهر) یک گروه مستقل خواهد بود.


🔹 گروه‌بندی موقعیتی: GROUP BY 1, 2

به جای نوشتن نام ستون‌ها، می‌توانید به شماره موقعیت آن‌ها در بخش SELECT اشاره کنید:

SELECT ship_country, ship_city, COUNT(*)
FROM orders
GROUP BY 1, 2;

برای کوئری‌های سریع مفید است، اما در گزارش‌های رسمی توصیه نمی‌شود (به خاطر خوانایی کمتر).


🔹 فیلتر کردن گروه‌ها با HAVING

برخلاف WHERE که قبل از گروه‌بندی اعمال می‌شود، HAVING بعد از انجام GROUP BY فیلتر را روی نتایج تجمیعی اعمال می‌کند.

SELECT ship_country, COUNT(*) AS total_orders
FROM orders
GROUP BY ship_country
HAVING COUNT(*) > 20
ORDER BY total_orders DESC;
تمرین‌ها:
  • فقط کشورهایی را نمایش دهید که بیش از ۱۵ سفارش دارند.
  • فقط شهرهایی را نمایش دهید که میانگین freight آن‌ها بالای ۱۰۰ است.

🔹 رفتار توابع تجمیعی با NULL

حالتتوضیح
COUNT(*)همه ردیف‌ها را می‌شمارد (حتی NULLها)
COUNT(column)فقط مقادیر غیر NULL را می‌شمارد
SUM, AVG, MIN, MAXمقادیر NULL را نادیده می‌گیرند
مثال:
SELECT 
    COUNT(fax) AS customers_with_fax,
    COUNT(*)   AS total_customers
FROM customers;

اگر از ۹۱ مشتری، ۸۰ تای آن‌ها شماره فکس دارند، ۱۱ تای بدون فکس در COUNT(fax) محاسبه نمی‌شوند.


🔹 تجمیع شرطی با CASE

با ترکیب CASE و توابع تجمیعی، می‌توان گزارش‌های تحلیلی دقیق‌تری ساخت:

SELECT
    ship_country,
    COUNT(*) AS total_orders,
    SUM(CASE WHEN freight > 100 THEN 1 ELSE 0 END) AS high_freight_orders,
    ROUND(AVG(CASE WHEN freight > 100 THEN freight END), 2) AS avg_high_freight
FROM orders
GROUP BY ship_country;

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


🔹 گزارش‌های کاربردی در Northwind

عنوان گزارشتوضیح
مجموع فروش هر سالاستفاده از EXTRACT(YEAR FROM order_date) در GROUP BY
۵ کشور برتر بر اساس میانگین هزینه حملترکیب Aggregate + ORDER BY + FETCH FIRST 5 ROWS
تعداد سفارش‌ها در هر ماه برای سال ۱۹۹۷استفاده از DATE_TRUNC('month', order_date) در GROUP BY

✅ جمع‌بندی

مفهومنکته کلیدیجدول نمونه
توابع تجمیعیCOUNT(), SUM(), AVG(), MIN(), MAX()orders
گروه‌بندی داده‌هاGROUP BY, GROUP BY 1, 2orders
فیلتر بعد از گروه‌بندیHAVINGorders
رفتار با NULLCOUNT(column) در برابر COUNT(*)customers
گزارش شرطیSUM(CASE WHEN …)orders
فروشگاه
جستجو
دوره ها

لطفا کلمات کلیدی را وارد کنید