تستعرض هذه المقالة العبارة CASE
، والتي تُستخدم لكتابة الشيفرات الشرطية (if-then).
استخدام CASE لحساب عدد الصفوف في العمود الذي يلبي شرطا معينًا
يمكن استخدام CASE
مع SUM
لحساب عدد العناصر المطابقة لشرط محدد (تشبه العبارة COUNTIF
في Excel.)
الحيلة التي سنعتمدها هي أنّنا سنعيد نتائج ثنائية (binary) للدلالة على مطابقة الشرط، حيث يشير 1 إلى أنّ المدخل يطابق الشرط، فيما يشير 0 إلى عدم المطابقة، بعد ذلك سنجمع الوحدات التي حصلنا عليها للحصول على عدد المطابقات.
في الجدول ItemSales
التالي، سنحاول عدّ العناصر الثمينة (EXPENSIVE):
Id | ItemId | Price | PriceRating |
---|---|---|---|
1 | 100 | 34.5 | EXPENSIVE |
2 | 145 | 2.3 | CHEAP |
3 | 100 | 34.5 | EXPENSIVE |
4 | 100 | 34.5 | EXPENSIVE |
5 | 145 | 10 | AFFORDABLE |
سنستخدم الاستعلام التالي:
SELECT COUNT(Id) AS ItemsCount, SUM ( CASE WHEN PriceRating = 'Expensive' THEN 1 ELSE 0 END ) AS ExpensiveItemsCount FROM ItemSales
سنحصل على الخرج التالي:
ItemsCount | ExpensiveItemsCount |
---|---|
5 | 3 |
هذا استعلام آخر بديل:
SELECT COUNT(Id) as ItemsCount, SUM ( CASE PriceRating WHEN 'Expensive' THEN 1 ELSE 0 END ) AS ExpensiveItemsCount FROM ItemSales
البحث الشرطي
يمكن استخدام CASE
مع العبارة SELECT
لتصفية النتائج حسب شرط معيّن، بحيث لا تُعاد إلا النتائج التي تعيد القيمة المنطقية TRUE
(هذا يختلف عن استخدام case العادي، والذي يتحقق من التكافؤ مع المُدخل وحسب).
SELECT Id, ItemId, Price, CASE WHEN Price < 10 THEN 'CHEAP' WHEN Price < 20 THEN 'AFFORDABLE' ELSE 'EXPENSIVE' END AS PriceRating FROM ItemSales
سنحصل على الخرج التالي:
Id | ItemId | Price | PriceRating |
---|---|---|---|
1 | 100 | 34.5 | EXPENSIVE |
2 | 145 | 2.3 | CHEAP |
3 | 100 | 34.5 | EXPENSIVE |
4 | 100 | 34.5 | EXPENSIVE |
5 | 145 | 10 | AFFORDABLE |
الشكل المُختزل لـ CASE
يقيّم الشكل المختزل لـ CASE
تعبيرًا ما (عادةً ما يكون عمودًا)، ويقارنه بعدة قيم. هذا الشكل أقصر قليلاً من الشكل العادي، ويُعفيك من تكرار التعبير المقيَّم.
يمكن استخدام صياغة ELSE
في الشكل على النحو التالي:
SELECT Id, ItemId, Price, CASE Price WHEN 5 THEN 'CHEAP' WHEN 15 THEN 'AFFORDABLE' ELSE 'EXPENSIVE' END as PriceRating FROM ItemSales
من المهم أن تدرك أنه عند استخدام الشكل المختصر، فسيُقيَّم التعبير بالكامل في كل عبارة WHEN
. لذلك، فإنّ الشيفرة التالية:
SELECT CASE ABS(CHECKSUM(NEWID())) % 4 WHEN 0 THEN 'Dr' WHEN 1 THEN 'Master' WHEN 2 THEN 'Mr' WHEN 3 THEN 'Mrs' END
قد تعيد القيمة المعدومة NULL
. لأنّه في كل عبارة WHEN
، تُستدعى NEWID()
مع نتيجة جديدة. هذا يكافئ:
SELECT CASE WHEN ABS(CHECKSUM(NEWID())) % 4 = 0 THEN 'Dr' WHEN ABS(CHECKSUM(NEWID())) % 4 = 1 THEN 'Master' WHEN ABS(CHECKSUM(NEWID())) % 4 = 2 THEN 'Mr' WHEN ABS(CHECKSUM(NEWID())) % 4 = 3 THEN 'Mrs' END
لذلك يمكن أن تُفوِّت جميع عبارات WHEN
، لتُنتج القيمة NULL
.
استخدام CASE في عبارة ORDER BY
في الشيفرة، أدناه سنستخدم الأرقام 1،2،3 .. لتصنيف الطلب إلى أنواع:
SELECT * FROM DEPT ORDER BY CASE DEPARTMENT WHEN 'MARKETING' THEN 1 WHEN 'SALES' THEN 2 WHEN 'RESEARCH' THEN 3 WHEN 'INNOVATION' THEN 4 ELSE 5 END, CITY
الخرج الناتج:
ID | REGION | CITY | DEPARTMENT | EMPLOYEES_NUMBER |
---|---|---|---|---|
12 | New England | Boston | MARKETING | 9 |
15 | West | San Francisco | MARKETING | 12 |
9 | Midwest | Chicago | SALES | 8 |
14 | Mid-Atlantic | New York | SALES | 12 |
5 | West | Los Angeles | RESEARCH | 11 |
10 | Mid-Atlantic | Philadelphia | RESEARCH | 13 |
4 | Midwest | Chicago | INNOVATION | 11 |
2 | Midwest | Detroit | HUMAN RESOURCES | 9 |
استخدام CASE في UPDATE
يزيد المثال التالي الأسعار في قاعدة البيانات:
UPDATE ItemPrice SET Price = Price * CASE ItemId WHEN 1 THEN 1.05 WHEN 2 THEN 1.10 WHEN 3 THEN 1.15 ELSE 1.00 END
استخدام CASE مع القيم المعدومة NULL
في هذا المثال، يمثل الرقم "0" االقيم المعروفة، والتي توضوع في البداية، فيما يمثل "1" القيم NULL
، و هي موضوعة في آخر الترتيب:
SELECT ID ,REGION ,CITY ,DEPARTMENT ,EMPLOYEES_NUMBER FROM DEPT ORDER BY CASE WHEN REGION IS NULL THEN 1 ELSE 0 END, REGION
سنحصل على الخرج التالي:
ID | REGION | CITY | DEPARTMENT | EMPLOYEES_NUMBER |
---|---|---|---|---|
10 | Mid-Atlantic | Philadelphia | RESEARCH | 13 |
14 | Mid-Atlantic | New York | SALES | 12 |
9 | Midwest | Chicago | SALES | 8 |
12 | New England | Boston | MARKETING | 9 |
5 | West | Los Angeles | RESEARCH | 11 |
15 | NULL | San Francisco | MARKETING | 12 |
4 | NULL | Chicago | INNOVATION | 11 |
2 | NULL | Detroit | HUMAN RESOURCES | 9 |
استخدام CASE في عبارة ORDER BY لترتيب السجلات حسب القيمة الدنيا لعمودين
لنفترض أنك بحاجة إلى ترتيب السجلات حسب القيمة الدنيا في عمودين. قد تستخدم بعض قواعد البيانات الدالتين غير التجميعيتين MIN()
أو LEAST()
(مثلا: ... ORDER BY MIN(Date1, Date2)
)، ولكن في SQL القياسية، يجب استخدام التعبير CASE
.
يبحث التعبير CASE
في الاستعلام أدناه في العمودين Date1
و Date2
، ويبحث عن العمود الذي له أدنى قيمة، ثم يرتب السجلات وفقًا لتلك القيمة.
إليك الجدول التالي:
Id | Date1 | Date2 |
---|---|---|
1 | 2017-01-01 | 2017-01-31 |
2 | 2017-01-31 | 2017-01-03 |
3 | 2017-01-31 | 2017-01-02 |
4 | 2017-01-06 | 2017-01-31 |
5 | 2017-01-31 | 2017-01-05 |
6 | 2017-01-04 | 2017-01-31 |
إليك الاستعلام التالي:
SELECT Id, Date1, Date2 FROM YourTable ORDER BY CASE WHEN COALESCE(Date1, '1753-01-01') < COALESCE(Date2, '1753-01-01') THEN Date1 ELSE Date2 END
الخرج النتائج:
Id | Date1 | Date2 |
---|---|---|
1 | 2017-01-01 | 2017-01-31 |
3 | 2017-01-31 | 2017-01-02 |
2 | 2017-01-31 | 2017-01-03 |
6 | 2017-01-04 | 2017-01-31 |
5 | 2017-01-31 | 2017-01-05 |
4 | 2017-01-06 | 2017-01-31 |
كما ترى ، الصف ذو المعّرف Id = 1
جاء أولًا، وذلك لأنّ العمود Date1
يحتوي أدنى سجل في الجدول، وهو 2017-01-01
، الصف ذو المعرّف Id
= 3
جاء ثانيًا، لأنّ العمود Date2
يحتوي القيمة2017-01-02
، وهي ثاني أقل قيمة في الجدول، وهكذا دواليك.
لقد رتّبنا السجلات من 2017-01-01
إلى 2017-01-06
تصاعديًا، بغض النظر عن العمود Date1
أو Date2
الذي جاءت منه تلك القيم.
ترجمة -وبتصرّف- للفصول 7 و8 و9 من الكتاب SQL Notes for Professionals
اقرأ أيضًا:
- المقال التالي: البحث والتنقيب والترشيح في SQL
- المقال السابق: التجميع والترتيب في SQL
- النسخة العربية الكاملة من كتاب ملاحظات للعاملين بلغة SQL 1.0.0
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.