با سلام و عرض ادب خدمت شما همراهان روکسو، در این جلسه می خواهیم دستور HAVING و اپراتور EXISTS (و فلسفه ی اضافه شدن آن به زبان SQL) را مورد بررسی قرار دهیم و برای هر کدام چند مثال نیز حل کنیم. با ما همراه باشید!
اضافه شدن دستور HAVING به زبان SQL داستان خودش را دارد. در واقع شما نمی توانید از توابع تجمیع (COUNT, MAX, MIN, SUM, AVG) به همراه دستور WHERE استفاده کنید اما بعضی اوقات به چنین حالتی نیاز داریم. بنابراین راه حل دستور HAVING بود که به این زبان اضافه شد. ساختار کلی این دستور به این شکل است:
SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s) HAVING condition ORDER BY column_name(s);
می خواهیم مثال های خود را روی جدول Customers پیاده کنیم بنابراین ابتدا نگاهی به آن می اندازیم:
Country | PostalCode | City | Address | ContactName | CustomerName | CustomerID |
Germany | 12209 | Berlin | Obere Str. 57 | Maria Anders | Alfreds Futterkiste | 1 |
Mexico | 05021 | México D.F. | Avda. de la Constitución 2222 | Ana Trujillo | Ana Trujillo Emparedados y helados | 2 |
Mexico | 05023 | México D.F. | Mataderos 2312 | Antonio Moreno | Antonio Moreno Taquería | 3 |
UK | WA1 1DP | London | 120 Hanover Sq. | Thomas Hardy | Around the Horn | 4 |
Sweden | S-958 22 | Luleå | Berguvsvägen 8 | Christina Berglund | Berglunds snabbköp | 5 |
مثال اول - دستور SQL زیر تعداد مشتریان هر کشور را به صورت لیست به ما بر میگرداند اما تنها شامل کشور هایی می شود که بیشتر از 5 مشتری داشته باشند:
SELECT COUNT(CustomerID), Country FROM Customers GROUP BY Country HAVING COUNT(CustomerID) > 5;
اجرای این دستور در پایگاه داده ی Northwind
مثال دوم - دستور SQL زیر تعداد مشتریان هر کشور را به صورت لیست به ما بر میگرداند اما تنها شامل کشور هایی می شود که بیشتر از 5 مشتری داشته باشند. آیا می توانید با نگاه کردن به کدها متوجه تفاوت این مثال با مثال قبلی شوید؟ بله! این دستور علاوه بر برگرداندن تعداد مشتری ها، آن ها را از بیشتری تعداد به کمترین تعداد نیز مرتب می کند:
SELECT COUNT(CustomerID), Country FROM Customers GROUP BY Country HAVING COUNT(CustomerID) > 5 ORDER BY COUNT(CustomerID) DESC;
اجرای این دستور در پایگاه داده ی Northwind
حالا به سراغ دو جدول دیگر می رویم. جدول Orders:
ShipperID | OrderDate | EmployeeID | CustomerID | OrderID |
3 | 1996-07-04 | 5 | 90 | 10248 |
1 | 1996-07-05 | 6 | 81 | 10249 |
2 | 1996-07-08 | 4 | 34 | 10250 |
و جدول Employees:
Notes | Photo | BirthDate | FirstName | LastName | EmployeeID |
Education includes a BA.... | EmpID1.pic | 1968-12-08 | Nancy | Davolio | 1 |
Andrew received his BTS.... | EmpID2.pic | 1952-02-19 | Andrew | Fuller | 2 |
Janet has a BS degree.... | EmpID3.pic | 1963-08-30 | Janet | Leverling | 3 |
مثال سوم - دستور SQL زیر کارمندانی را لیست می کند که بیشتر از 10 سفارش ثبت کرده باشند:
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders FROM (Orders INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID) GROUP BY LastName HAVING COUNT(Orders.OrderID) > 10;
اجرای این دستور در پایگاه داده ی Northwind
مثال چهارم - دستور SQL زیر چک می کند تا ببیند آیا کارمندانی به نام های Davolio و Fuller بیشتر از 25 سفارش ثبت کرده اند یا خیر. اگر بیشتر از 25 سفارش ثبت کرده باشند آن ها را لیست می کند:
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders FROM Orders INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID WHERE LastName = 'Davolio' OR LastName = 'Fuller' GROUP BY LastName HAVING COUNT(Orders.OrderID) > 25;
اجرای این دستور در پایگاه داده ی Northwind
از این اپراتور برای چک کردن وجود یا عدم وجود یک ردیف در یک کوئری استفاده می شود.
اگر ردیف ما در کوئری وجود داشته باشد مقدار true
و در غیر این صورت مقدار false
برگردانده خواهد شد. ساختار کلی این دستور از قرار زیر است:
SELECT column_name(s) FROM table_name WHERE EXISTS (SELECT column_name FROM table_name WHERE condition);
میخواهیم دستورات خود را روی دو جدول Products و Suppliers پیاده سازی کنیم بنابراین ابتدا نگاهی به این دو جدول می اندازیم:
جدول Products:
Price | Unit | CategoryID | SupplierID | ProductName | ProductID |
18 | 10 boxes x 20 bags | 1 | 1 | Chais | 1 |
19 | 24 - 12 oz bottles | 1 | 1 | Chang | 2 |
10 | 12 - 550 ml bottles | 2 | 1 | Aniseed Syrup | 3 |
22 | 48 - 6 oz jars | 2 | 2 | Chef Anton's Cajun Seasoning | 4 |
21.35 | 36 boxes | 2 | 2 | Chef Anton's Gumbo Mix | 5 |
جدول Suppliers:
Country | PostalCode | City | Address | ContactName | SupplierName | SupplierID |
UK | EC1 4SD | London | 49 Gilbert St. | Charlotte Cooper | Exotic Liquid | 1 |
USA | 70117 | New Orleans | P.O. Box 78934 | Shelley Burke | New Orleans Cajun Delights | 2 |
USA | 48104 | Ann Arbor | 707 Oxford Rd. | Regina Murphy | Grandma Kelly's Homestead | 3 |
Japan | 100 | Tokyo | 9-8 Sekimai Musashino-shi | Yoshi Nagase | Tokyo Traders | 4 |
مثال اول - دستور SQL زیر مقدار TRUE را بر میگرداند و تامین کننده هایی (suppliers) را که دارای محصولاتی پایین تر از 20 دلار هستند لیست می کند:
SELECT SupplierName FROM Suppliers WHERE EXISTS (SELECT ProductName FROM Products WHERE SupplierId = Suppliers.supplierId AND Price < 20);
اجرای این دستور در پایگاه داده ی Northwind
مثال دوم - دستور SQL زیر مقدار TRUE را بر میگرداند و تامین کننده هایی (suppliers) را که قیمت یک یا چند عدد از محصولاتشان 22 است را لیست می کند:
SELECT SupplierName FROM Suppliers WHERE EXISTS (SELECT ProductName FROM Products WHERE SupplierId = Suppliers.supplierId AND Price = 22);
اجرای این دستور در پایگاه داده ی Northwind
امیدوارم این قسمت مورد پسند شما واقع شده باشد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.