دستور GROUP BY در SQL چطور کار می‌کند
آموزش

دستور GROUP BY در SQL چطور کار می‌کند

عملکرد دستور GROUP BY در SQL و نحوه گروه‌بندی سطرها به همراه توابع تجمیعی را با مثال‌های واقعی یاد بگیرید.

تحریریه‌ی دینا کد
نویسنده
۵ دقیقه مطالعه۷ بازدید
اشتراک گذاری۷
فهرست مطالب
  1. ۱منطق پایه‌ای GROUP BY در پردازش پرس‌وجو
  2. ۲یک نمونه عملی با جدول سفارش‌ها
  3. ۳خطای رایج انتخاب ستون‌های نامعتبر
  4. ۴تفاوت فیلتر با WHERE و فیلتر با HAVING
  5. ۵قدم بعدی برای یادگیری عمیق‌تر

وقتی می‌خواهید از میان هزاران سطر داده در پایگاه داده، اطلاعات آماری استخراج کنید، انتخاب تک‌تک سطرها راهگشا نیست. برای مثال، اگر بخواهید بدانید هر مشتری مجموعاً چقدر خرید کرده یا در هر بخش شرکت چند کارمند مشغول به کارند، باید سطرها را دسته‌بندی کنید و از هر دسته یک سطر خروجی بسازید. این دقیقاً همان نقطه‌ای است که دستور GROUP BY در SQL وارد میدان می‌شود.

منطق پایه‌ای GROUP BY در پردازش پرس‌وجو

طبق استاندارد SQL و مستندات رسمی PostgreSQL در پردازش عبارت‌های جدول (Table Expressions)، پردازش داده‌ها در پایگاه داده یک خط لوله منظم را طی می‌کند. ابتدا عبارت FROM جدول یا جداول مبدأ را مشخص می‌کند. سپس شرط‌های WHERE سطرهای نامرتبط را فیلتر می‌کنند. در مرحله بعد، دستور GROUP BY سطرهایی را که مقادیر یکسانی در ستون‌های مشخص‌شده دارند در یک گروه ادغام می‌کند.

نتیجه این گروه‌بندی، ایجاد سطرهای خلاصه‌شده است. وقتی سطری را گروه‌بندی می‌کنید، پایگاه داده دیگر دسترسی به داده‌های منحصر‌به‌فرد تک‌تک سطرهای آن گروه به شکل عادی ندارد؛ مگر اینکه از «توابع تجمیعی» (Aggregate Functions) مانند SUM، COUNT، AVG، MAX یا MIN استفاده کنید.

یک نمونه عملی با جدول سفارش‌ها

فرض کنید جدولی به نام orders داریم که ثبت خریدهای کاربران را نگه می‌دارد:

text customer_id | amount 
-------------+--------
           ۱ |    ۱۰۰
           ۱ |    ۲۵۰
           ۲ |    ۳۰۰
           ۳ |    ۱۵۰
           ۲ |     ۵۰

می‌خواهیم مجموع پرداخت‌ها و تعداد سفارش‌های هر مشتری را محاسبه کنیم. کوئری زیر این کار را انجام می‌دهد:

sql-- محاسبه تعداد خرید و مجموع واریزی هر کاربر
SELECT 
    customer_id,
    COUNT(*) AS total_orders,
    SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id;

خروجی این کوئری به شکل زیر خواهد بود:

text customer_id | total_orders | total_spent 
-------------+--------------+-------------
           ۱ |            ۲ |         ۳۵۰
           ۲ |            ۲ |         ۳۵۰
           ۳ |            ۱ |         ۱۵۰

موتور پایگاه داده سطرهای متعلق به customer_id = ۱ را کنار هم گذاشت، تابع COUNT تعداد آن‌ها را شمرد و تابع SUM مقادیر ستون amount را برای آن گروه با هم جمع زد.

خطای رایج انتخاب ستون‌های نامعتبر

رایج‌ترین خطایی که برنامه‌نویسان تازه‌کار با آن مواجه می‌شوند، فراخوانی ستونی در بخش SELECT است که نه در عبارت GROUP BY آمده و نه داخل یک تابع تجمیعی قرار دارد. برای مثال به این کوئری ناقص نگاه کنید:

sql-- این کوئری در پایگاه‌های داده استاندارد مانند PostgreSQL با خطا مواجه می‌شود
SELECT customer_id, order_date, SUM(amount)
FROM orders
GROUP BY customer_id;

این دستور خطای سینتکسی برمی‌گرداند. دلیل خطاست: مشتری شماره ۱ دارای دو سفارش در دو تاریخ مختلف است. پایگاه داده نمی‌داند برای یک سطر خروجی این مشتری، کدام تاریخ را چاپ کند. قانون طلایی این است: هر ستونی که در SELECT می‌آید یا باید در GROUP BY ذکر شود، یا در دل یک تابع تجمیعی مثل MIN(order_date) قرار بگیرد.

تفاوت فیلتر با WHERE و فیلتر با HAVING

یکی دیگر از سردرگمی‌ها، فیلتر کردن نتایج گروه‌بندی است. دستور WHERE قبل از اجرای گروه‌بندی، سطرها را ارزیابی می‌کند. بنابراین نمی‌توانید از توابع تجمیعی در WHERE استفاده کنید. اگر بخواهید گروه‌ها را بر اساس خروجی محاسبات تجمیعی فیلتر کنید، باید از عبارت HAVING بهره ببرید:

sql-- نمایش فقط مشتریانی که بیشتر از ۲۰۰ واحد مجموع خرید داشته‌اند
SELECT 
    customer_id,
    SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > ۲۰۰;

در این سناریو، ابتدا گروه‌بندی انجام می‌شود، سپس شرط HAVING روی نتایج حاصل از تجمیع هر گروه اعمال می‌گردد.

قدم بعدی برای یادگیری عمیق‌تر

اکنون که سازوکار پایه‌ای گروه‌بندی و ترکیب آن با توابع محاسباتی را شناختید، گام بعدی یادگیری دستورهای پیشرفته‌تری مثل GROUPING SETS و ROLLUP برای گزارش‌گیری چندسطحی است. برای یادگیری ساختار جداول، کلیدهای خارجی و نوشتن کوئری‌های پیچیده می‌توانید سرفصل‌های دوره پایگاه داده و SQL را دنبال کنید.

تحریریه‌ی دینا کد
نویسنده

نظرها

اولین نفری باشید که نظر می‌دهد
برای ثبت نظر وارد شوید

سؤالتان را بپرسید یا تجربه‌تان را بنویسید تا نویسنده‌ی مطلب پاسخ بدهد.

مطالب مرتبط

از همین دسته
کلید اصلی و کلید خارجی در SQL
آموزش

کلید اصلی و کلید خارجی در SQL

راهنمای تعریف کلید اصلی و کلید خارجی در SQL برای تضمین یکتایی سطرها و حفظ یکپارچگی ارجاعی داده‌ها.

تحریریه‌ی دینا کد۶ دقیقه
struct در Go چیست و چه فرقی با کلاس دارد
آموزش

struct در Go چیست و چه فرقی با کلاس دارد

ساختار داده struct در زبان Go جایگزین کلاس‌های مرسوم شیءگرایی است و چگونگی گروه‌بندی داده‌ها و متدها را به شیوه‌ای ساده‌تر ممکن می‌سازد.

تحریریه‌ی دینا کد۷ دقیقه