در این مطلب از مجله فرادرس به بررسی دستور Having در SQL خواهیم پرداخت. در SQL از کلمه کلیدی Having دقیقا بعد از عبارت GROUP BY استفاده میکنیم تا برای پایگاه داده بر اساس شرایط خود کوئری بنویسیم. مانند بقیه کلمات کلیدی، این عبارت دادهها را با توجه به شرایط خود انتخاب میکند و باقی دادهها را فیلتر میکند. کلمه کلیدی Having به این دلیل معرفی شد که عبارت WHERE در زمان کار با «توابع تجمعی» (Aggregate Functions) خوب عمل نمیکرد. درنتیجه وقتی از تابعهای تجمعی استفاده میکنیم بهجای عبارت WHERE باید از عبارت Having استفاده کنیم. عبارت Having کمک میکند که فرایند انبوهش با دقت بالاتری اتفاق بیافتد.
«انبوهش» (Aggregation) نام دیگری برای فرایند جمع و خلاصهسازی نقاط داده در یک داده مجزا است. برای نمونه میتوان از فرایندهایی مانند محاسبه میانگین یا حداقل در مجموعهای از دادهها نام برد. بعضی وقتها نیز، انبوهش مجموعهای از دادهها به داده خاصی تبدیل میشود که کاربردی ندارد. برای مثال فرض کنیم درحال بررسی رفتارهای مربوط به خرید در فروشگاه خود هستید و مشتریان فروشگاه، ترکیبی از دو دسته دانشآموزان ضعیف و اساتید ثروتمند هستند. در این شرایط، اگر رفتار هر گروه را بهصورت جداگانه بررسی کنید اطلاعات بسیار با ارزشتری بدست خواهید آورد. به عبارت دیگر باید مبلغ پولی را که هزینه شده در نهایت جمع ببندید اما اطلاعات مربوط به این پول، باید با توجه به هر گروه از مشتریان بهصورت جداگانه پردازش شود. مخلوط کردن یا انبوهش دادههای همه مشتریها اطلاعات کم ارزشی به شما خواهد داد.
عبارت HAVING در SQL
عبارت HAVING در SQL شبیه به عبارت WHERE است. هر دو برای فیلتر كردن سطرها در جدول بر اساس معیارهای مشخصی استفاده میشوند. عبارت HAVING برای فیلتر كردن سطرهایی كه گروهبندی شدهاند استفاده میشود بجای اینكه سطرها را بهصورت مجزا از هم فیلتر كند. این سطرها به وسیله عبارت GROUP BY قبلا گروهبندی شدهاند. بنابراین، عبارت HAVING همیشه در كوئری بعد از ماده GROUP BY میآید.
علاوه براین، از ماده HAVING
در كوئری میتوان همراه با «توابع تجمعی» (Aggregate Functions) مانند COUNT()
, SUM()
, AVG()
و غیره استفاده كرد. درحالی كه عبارت WHERE
را نمیتوان با توابع تجمعی استفاده كرد.
سینتكس دستور HAVING در SQL
كدی كه در پایین میبینید سینتكس پایه دستور HAVING در SQL است.
1SELECT column1, column2, aggregate_function(column)
2FROM table_name
3GROUP BY column1, column2
4HAVING condition;
بلاك كدی كه در ادامه آمده است موقعیت عبارت HAVING
را بهصورت كلی در كوئری نشان میدهد.
1SELECT
2FROM
3WHERE
4GROUP BY
5HAVING
6ORDER BY
همینطور كه میبینید عبارت HAVING
بعد از همهی عبارتهای كلیدی به غیر از ORDER BY
آمده است.
عبارت HAVING همراه با دستور GROUP BY
میتوانیم از عبارت HAVING
همراه با دستور GROUP BY
استفاده كنیم تا گروههایی از سطرها را تحت شرایط مشخص فیلتر كنیم. پس از اعمال «انبوهش» (Aggregation) بر روی دادهها از این دستور برای اعمال فیلتر روی مجموعه نتایج استفاده میشود.
مثال
فرض كنید جدولی به نام مشتریها CUSTOMERS
با استفاده از كوئری زیر ایجاد كردهایم كه شامل نام، سن، آدرس، و درآمد مشتریان میشود. ستونها را به ترتیب به نامهای address ،age ،name و salary نامگزاری كردهایم. به كوئری زیر نگاه كنید.
1CREATE TABLE CUSTOMERS (
2 ID INT NOT NULL,
3 NAME VARCHAR (20) NOT NULL,
4 AGE INT NOT NULL,
5 ADDRESS CHAR (25),
6 SALARY DECIMAL (18, 2),
7 PRIMARY KEY (ID)
8);
الان با استفاده از عبارت INSERT
بهصورتی كه در زیر آمده است مقادیری را درون جدول وارد كنید.
1INSERT INTO CUSTOMERS VALUES
2(1, 'Ramesh', 32, 'Ahmedabad', 2000.00),
3(2, 'Khilan', 25, 'Delhi', 1500.00),
4(3, 'Kaushik', 23, 'Kota', 2000.00),
5(4, 'Chaitali', 25, 'Mumbai', 6500.00),
6(5, 'Hardik', 27, 'Bhopal', 8500.00),
7(6, 'Komal', 22, 'Hyderabad', 4500.00),
8(7, 'Muffy', 24, 'Indore', 10000.00);
میتوانید در تصویر زیر جدولی را كه با استفاده از كدهای بالا ساخته شده، ببینید.
SALARY | ADDRESS | AGE | NAME | ID |
2000 | Ahmedabad | 32 | Ramesh | 1 |
1500 | Delhi | 25 | Khilan | 2 |
2000 | Kota | 23 | Kaushik | 3 |
6500 | Mumbai | 25 | Chaitali | 4 |
8500 | Bhopal | 27 | Hardik | 5 |
4500 | Hyderabad | 22 | Komal | 6 |
10000 | Indore | 24 | Muffy | 7 |
الان درحال دستهبندی ركوردهای جدول CUSTOMERS
بر اساس ستونهای آدرس ADDRESS
و سن AGE
هستیم و گروهها را با این شرط كه مقدار AGE
كمتر از 25
باشد فیلتر میكنیم.
1SELECT ADDRESS, AGE, MIN(SALARY) AS MIN_SUM
2FROM CUSTOMERS
3GROUP BY ADDRESS, AGE HAVING AGE > 25;
خروجی
خروجی تولید شده توسط كد بالا به شكل زیر است.
MIN_SUM | AGE | ADDRESS |
---|---|---|
2000 | 32 | Ahmedabad |
8500 | 27 | Bhopal |
عبارت HAVING همراه با دستور ORDER BY
از عبارت ORDER BY
برای منظم كردن ركوردهای منتج شده توسط كوئری SELECT بر پایه ستونهای مشخص در کوئری استفاده میشود. عبارت ORDER BY
میتواند دادهها را بهصورت صعودی یا نزولی منظم كند. با استفاده از عبارت ORDER BY
در كنار عبارت HAVING
میتوانیم با نظم دلخواه خود، دادههای گروههای فیلتر شده را منظم كنیم.
مثال
كوئری كه در ادامه آمده است ركوردهای جدول CUSTOMERS
را بر اساس سن AGE
و آدرس ADDRESS
دستهبندی میكند. سپس گروهها را به شرطی كه مقدار حقوق SALARY
كمتر از 5000
باشد فیلتر میكند. در آخر نیز باقیمانده گروهها را بهصورت نزولی بر اساس كل حقوق هر گروه منظم میكند.
1SELECT ADDRESS, AGE, SUM(SALARY) AS TOTAL_SALARY
2FROM CUSTOMERS
3GROUP BY ADDRESS, AGE HAVING TOTAL_SALARY >=5000
4ORDER BY TOTAL_SALARY DESC;
خروجی
نتایجی كه از كوئری بالا بهدست میآید در جدول زیر دیده میشود.
TOTAL_SALARY | AGE | ADDRESS |
10000 | 24 | Indore |
8500 | 27 | Bhopal |
6500 | 25 | Mumbai |
دستور HAVING همراه با توابع تجمعی
عبارت WHERE در زمان کار همراه با «توابع تجمعی» (Aggregate Functions) خوب عمل نمیکرد. درنتیجه هنگام استفاده از تابعهای تجمعی باید بهجای عبارت WHERE، از عبارت Having استفاده کنیم. در ادامه این نوع خاص از توابع و روش استفاده از دستور HAVING به همراه بعضی از این تابعها را بررسی کردهایم.
تابع تجمعی در SQL چیست؟
تابع تجمعی به نوعی از تابع میگویند که روی چندین داده مختلف محاسباتی انجام میدهد و به عنوان خروجی فقط یک مقدار برمیگرداند. SQL توابع تجمعی زیادی ارائه داده است که به عنوان مثال میتوان به مواردی مانند گزینههای فهرست شده در زیر اشاره کرد.
- Max
- Min
- Sum
- Count
- Avg
- و غیره
از این تابعها اغلب به همراه عبارتهای GROUP BY و HAVING در دستور SELECT استفاده میشود. همه توابع تجمعی در زمان محاسباتشان مقادیر NULL را نادیده میگیرند به غیر از تابع Count()
.
در ادامه به بررسی بعضی از این توابع میپردازیم. بررسی خود را با تابع Count()
شروع خواهیم کرد.
دستور HAVING به همراه تابع COUNT
میتوان از دستور HAVING در SQL همراه با تابع COUNT()
برای فیلتركردن گروهها بر اساس سطرهایی كه دارند استفاده كرد.
مثال
كوئری كه در ادامه آمده است ركوردهای جدول CUSTOMERS
را بر اساس ستون سن AGE
مشتریها دستهبندی میكند و دادهها را از دستههایی که بیش از دو عضو دارند میخواند.
1SELECT AGE, COUNT(AGE)
2FROM CUSTOMERS GROUP BY AGE HAVING COUNT(age) > 2;
خروجی
خروجی زیر از اجرای کد بالا بر روی جدول مشتریان بهدست میآید.
Query OK, 0 rows affected (0.02 sec)
دستور HAVING به همراه تابع AVG
دستور HAVING در SQL به همرا تابع AVG()
نیز قابل استفاده است. از ترکیب این عبارتها برای فیلتر کردن گروهها بر اساس مقدار میانگین در ستون خاصی استفاده میکنند.
مثال
در مثال بعد میخواهیم دادههای شهرهایی را فراخوانی کنیم که مشتریان آن شهرها دارای میانگین حقوق بالاتر از ۵۲۴۰ هستند. به کوئری که در ادامه آمده نگاه کنید.
1SELECT ADDRESS, AVG(SALARY) as AVG_SALARY
2FROM CUSTOMERS
3GROUP BY ADDRESS HAVING AVG(SALARY) > 5240;
خروجی
مجموعه نتایجی که بهصورت جدول در زیر میبینید بر اثر اجرای کوئری بالا از جدول مشتریها ایجاد شدهاند.
AVG_SALARY | ADDRESS |
6500 | Mumbai |
8500 | Bhopal |
10000 | Indore |
دستور HAVING به همراه تابع MAX
تابع MAX()
یکی دیگر از توابع تجمعی است که همراه با دستور HAVING در SQL مورد استفاده قرار میگیرد. از این تابع برای فیلتر کردن گروهها بر اساس مقدار ماکزیمم از ستون خاصی استفاده میشود.
مثال
به کمک تابع MAX()
و دستور HAVING در SQL در مثالی که آوردهایم به دنبال استخراج شهرهایی از جدول مشتریها هستیم که بیشترین حقوق مشتریها در آنجا از ۵۲۴۰ بالاتر است. به کوئری آمده در پایین توجه کنید.
1SELECT ADDRESS, MAX(SALARY) as MAX_SALARY
2FROM CUSTOMERS
3GROUP BY ADDRESS HAVING MAX(SALARY) > 5240;
خروجی
مجموعهی نتایج ناشی از کوئری بالا بهصورت زیر خواهد بود.
MAX_SALARY | ADDRESS |
6500 | Mumbai |
8500 | Bhopal |
10000 | Indore |
سوالات متداول
در این بخش به بررسی بعضی از سوالاتی میپردازیم که بیشتر از همه برای کاربران پیش آمدهاند و شاید برای شما هم مطرح شده باشند.
چه تفاوتی بین دستور WHERE و دستور HAVING در SQL وجود دارد؟
تفاوت اصلی بین عبارتهای HAVING و WHERE این است که عبارت WHERE به کاربران اجازه میدهد که دادهها را از سطرهای مشخصی از جدول بر اساس معیارهای تعیین شده فیلتر کند. در مقابل آن، عبارت HAVING به کاربران اجازه میدهد که دادهها را از بین گروهی از ردیفها در کوئری بر اساس شرطهای مشخص شده فیلتر کند. این شرطها شامل توابع تجمعی نیز میشوند.
آیا می توانم از عبارت HAVING بدون عبارت GROUP BY استفاده کنم؟
اگر از دستور HAVING در SQL بدون عبارت GROUP BY استفاده کنید، شرایط عبارت HAVING بر روی همه سطرهای واجد شرایط جستوجو اعمال میشود به عبارت دیگر، همه سطرهایی که شرایط جستوجو را تامین میکنند، یک گروه مجزا را تشکیل میدهند.
آیا می توانیم از عبارت های HAVING و WHERE همزمان باهم در یک کوئری استفاده کنیم؟
بله، قطعا میتوانید در همان کوئری که عبارت HAVING را بکاربردهاید، از عبارت WHERE نیز استفاده کنید. وقتی عبارت WHERE را در همان کوئری به کار میگیرید همیشه باید قبل از عبارت GROUP BY استفاده شود که به همین ترتیب همیشه قبل از دستور HAVING در SQL استفاده میشود. در نتیجه همیشه دادهها اول از همه با شرایط مربوط به عبارت WHERE فیلتر میشوند.
جمع بندی
به کمک عبارت HAVING و کلمه کلیدی GROUP BY میتوانیم دادههای پایگاه داده خود را در گروههای مختلفی دستهبندی کنیم. از این عبارت در پایگاههای داده بزرگ هم میتوان استفاده کرد. در موقعیتهایی که نمیتوانید از دستور HAVING استفاده کنید، احتمالا ناچار به استفاده از عبارت WHERE خواهید بود.
در این مطلب از مجله فرادرس با دستور HAVING در SQL آشنا شدیم و یاد گرفتیم که در پایگاه داده با استفاده از عبارت HAVING به جستوجو بپردازیم. فراموش نکنید برای بهدست آوردن دادههای مطلوب نظرتان، همینطور که در این مطلب دیدید، از عبارت HAVING باید حتما در بند GROUP BY کوئری استفاده کنید. برای پیدا کردن اطلاعات بیشتر درباره سایر دستورات مربوط به SQL میتوانید به مجله فرادرس مراجعه کنید.
بدون کد ۱۱۹۵ کلمه
source