Məzmuna keç
Educora
İrəli18 dəq15 / 22

CASE və şərti məntiq

CASE WHEN ilə sorğunun içində «əgər... onda...» yaz, COALESCE və NULLIF ilə NULL-u idarə et, şərti aqreqasiya ilə cədvəli pivot formasına sal.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Axtarış və sadə CASE ifadələrini SELECT və ORDER BY-da işlətmək
  • COALESCE və NULLIF ilə NULL-u əvəz etmək və sıfıra bölmədən qorunmaq
  • Şərti aqreqasiya ilə sətirləri sütunlara çevirən (pivot) hesabat qurmaq

Elektron jurnal balı göstərəndə yanında hərfli qiymət də yazır: 94 — «A», 81 — «B». Onlayn mağaza məhsulun yanında «anbarda yoxdur» yazır, direktor isə şəhərlər və siniflər üzrə şagirdlərin sayını bir cədvəldə görmək istəyir. Bütün bunlar sorğunun içindəki şərtlərdir və SQL-də onları CASE ifadəsi ilə yazırıq. CASE digər proqramlaşdırma dillərindəki if kimidir, amma əmr yox, qiymət qaytaran ifadədir — ona görə onu sütun yazılan hər yerdə işlətmək olar.

Axtarış CASE-i: CASE WHEN ... THEN ... END

VBİS WHEN şərtlərini yuxarıdan aşağı yoxlayır və ilk doğru şərtin THEN qiymətini qaytarır; qalan şərtlərə artıq baxmır. Heç bir şərt doğru deyilsə, ELSE qiyməti, ELSE yazılmayıbsa, NULL qaytarılır. İfadə həmişə END ilə bitir və ona adətən AS ilə ad verilir.

SQL
SELECT s.first_name, e.score,
       CASE
         WHEN e.score >= 90 THEN 'A'
         WHEN e.score >= 80 THEN 'B'
         WHEN e.score >= 70 THEN 'C'
         ELSE 'D'
       END AS letter
FROM enrollments AS e
JOIN students AS s ON s.id = e.student_id
WHERE e.course_id = 3
ORDER BY e.score DESC;
▸ Gözlənilən nəticə
first_name | score | letter
Fidan | 94 | A
Murad | 81 | B
Rəşad | 77 | C
Elvin | 68 | D
Mechanics kursunun balları hərfli qiymətlərlə.

Sadə CASE və CASE ilə sıralama

Bir sütunu bir neçə konkret qiymətlə müqayisə edəndə qısa forma var: CASE sütun WHEN qiymət THEN ... END. Bu, = ilə yoxlamanın qısaltmasıdır. CASE-i ORDER BY-da da yazmaq olar: aşağıda müştəriləri valyuta ilə göstəririk, Azərbaycan müştərilərini isə siyahının əvvəlinə çıxarırıq.

SQL
SELECT name, country,
       CASE country
         WHEN 'Azerbaijan'     THEN 'AZN'
         WHEN 'Türkiye'        THEN 'TRY'
         WHEN 'Russia'         THEN 'RUB'
         WHEN 'United Kingdom' THEN 'GBP'
       END AS currency
FROM customers
ORDER BY CASE WHEN country = 'Azerbaijan' THEN 0 ELSE 1 END, name;
▸ Gözlənilən nəticə
name | country | currency
Anar Mustafayev | Azerbaijan | AZN
Lalə Əhmədova | Azerbaijan | AZN
Zəhra Hüseynli | Azerbaijan | AZN
Emre Yılmaz | Türkiye | TRY
John Carter | United Kingdom | GBP
Mehmet Kaya | Türkiye | TRY
Olga Ivanova | Russia | RUB

COALESCE və NULLIF

COALESCE(a, b, c) siyahıdakı ilk NULL olmayan qiyməti qaytarır — bu, CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ELSE c END-in qısa yazılışıdır. NULLIF(a, b) isə əksini edir: a = b olanda NULL, əks halda a qaytarır. Onun əsas işi sıfıra bölməni zərərsizləşdirməkdir: x / NULLIF(y, 0) ifadəsində y sıfır olanda bölünən NULL-a bölünür və nəticə NULL olur.

SQL
SELECT p.name, p.stock,
       COALESCE(SUM(o.quantity), 0) AS sold,
       ROUND(1.0 * COALESCE(SUM(o.quantity), 0) / NULLIF(p.stock, 0), 3) AS sold_per_stock
FROM products AS p
LEFT JOIN orders AS o ON o.product_id = p.id
WHERE p.category = 'Electronics'
GROUP BY p.id, p.name, p.stock
ORDER BY p.id;
▸ Gözlənilən nəticə
name | stock | sold | sold_per_stock
Laptop | 8 | 1 | 0.125
Smartphone | 15 | 2 | 0.133
Headphones | 40 | 3 | 0.075
Monitor | 0 | 0 | NULL
Anbarda qalmayan Monitor üçün bölmə NULL verir, xəta yox.

Şərti aqreqasiya və pivot

CASE aqreqatın içində yazılanda çox güclü alətə çevrilir. SUM(CASE WHEN şərt THEN 1 ELSE 0 END) şərti ödəyən sətirləri sayır. Bir neçə belə sütun yazsaq, sətirlərdəki qiymətlər sütunlara çevrilir — Excel-dəki pivot cədvəl kimi. Aşağıda hər şəhər üçün siniflər üzrə şagird sayını görürük.

SQL
SELECT city,
       SUM(CASE WHEN grade = 8  THEN 1 ELSE 0 END) AS g8,
       SUM(CASE WHEN grade = 9  THEN 1 ELSE 0 END) AS g9,
       SUM(CASE WHEN grade = 10 THEN 1 ELSE 0 END) AS g10,
       SUM(CASE WHEN grade = 11 THEN 1 ELSE 0 END) AS g11,
       COUNT(*) AS total
FROM students
GROUP BY city
ORDER BY total DESC, city;
▸ Gözlənilən nəticə
city | g8 | g9 | g10 | g11 | total
Bakı | 1 | 2 | 1 | 0 | 4
Gəncə | 0 | 0 | 1 | 1 | 2
Sumqayıt | 1 | 0 | 0 | 1 | 2
Lənkəran | 1 | 0 | 0 | 0 | 1
Naxçıvan | 0 | 0 | 0 | 1 | 1
Quba | 0 | 0 | 1 | 0 | 1
Şəki | 0 | 1 | 0 | 0 | 1

Eyni üsulla payları da hesablamaq olar: 0 və 1-lərin ortası şərti ödəyən sətirlərin payıdır. COUNT(CASE WHEN şərt THEN 1 END) də işləyir, çünki ELSE olmayanda qiymət NULL olur, COUNT isə NULL-ları saymır.

SQL
SELECT c.title,
       COUNT(*) AS students,
       COUNT(CASE WHEN e.score >= 90 THEN 1 END) AS excellent,
       ROUND(100.0 * AVG(CASE WHEN e.score >= 90 THEN 1 ELSE 0 END), 1) AS excellent_pct
FROM enrollments AS e
JOIN courses AS c ON c.id = e.course_id
GROUP BY c.id, c.title
ORDER BY excellent_pct DESC, c.title;
▸ Gözlənilən nəticə
title | students | excellent | excellent_pct
Python Basics | 3 | 2 | 66.7
Algebra | 4 | 2 | 50
English B1 | 2 | 1 | 50
World History | 2 | 1 | 50
Geometry | 3 | 1 | 33.3
Mechanics | 4 | 1 | 25
Organic Chemistry | 2 | 0 | 0
Nə edirikSQLitePostgreSQLMySQLSQL Server
Qısa ifIIF(c, a, b)CASEIF(c, a, b)IIF(c, a, b)
Şərtli saymaCOUNT(*) FILTER (WHERE c)COUNT(*) FILTER (WHERE c)SUM(c)SUM(CASE ...)
Hazır pivotyoxdurcrosstab (tablefunc əlavəsi)yoxdurPIVOT
CASE isə bütün VBİS-lərdə eyni işləyir — portativ sorğular üçün onu seç. MySQL-də müqayisə 1 və ya 0 qaytardığı üçün SUM(score >= 90) də sayır.
Tapşırıq

Hər məhsul üçün adı, qalığı (stock) və statusu (status) göstər: qalıq 0-dırsa — 'out of stock', 20-dən azdırsa — 'low', qalan hallarda — 'ok'. Nəticəni qalığa, sonra ada görə düz.

Tapşırıq · SQL
SELECT name, stock
       -- add the status column with CASE
FROM products
ORDER BY stock, name;
▸ Gözlənilən nəticə
name | stock | status
Monitor | 0 | out of stock
Laptop | 8 | low
Smartphone | 15 | low
Chess set | 18 | low
Desk lamp | 25 | ok
Headphones | 40 | ok
Backpack | 60 | ok
Water bottle | 120 | ok
Pen set | 300 | ok
Notebook | 500 | ok
Tapşırıq

Pivot hesabat qur: hər ölkə (country) üçün sifariş edilmiş Electronics məhsullarının ümumi ədədini (electronics) və digər kateqoriyaların ümumi ədədini (other) göstər. Nəticəni ölkəyə görə düz.

Tapşırıq · SQL
SELECT c.country
       -- electronics and other
FROM orders AS o
JOIN customers AS c ON c.id = o.customer_id
JOIN products  AS p ON p.id = o.product_id
GROUP BY c.country
ORDER BY c.country;
▸ Gözlənilən nəticə
country | electronics | other
Azerbaijan | 5 | 33
Russia | 0 | 1
Türkiye | 1 | 5
United Kingdom | 0 | 2

Əsas fikirlər

  • CASE WHEN ... THEN ... ELSE ... END ilk doğru şərtin qiymətini qaytarır; ELSE olmasa, NULL alınır.
  • Şərtləri ən dardan ən genişə doğru yaz; CASE SELECT, ORDER BY, WHERE və aqreqatların içində işləyir.
  • COALESCE ilk NULL olmayan qiyməti verir, NULLIF(y, 0) isə sıfıra bölmədən qoruyur.
  • SUM(CASE WHEN şərt THEN 1 ELSE 0 END) sayır, AVG(...) isə pay verir — pivot hesabatların əsası budur.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
CASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' WHEN score >= 70 THEN 'C' ELSE 'D' END ifadəsi 85 bal üçün nə qaytarır?