Bu gün bir az daha spesifik, amma vacib bir mövzuya baş vururuq: GREATEST() və LEAST() funksiyaları. Sən öyrənəcəksən ki, bir neçə sütundan maksimum və minimum dəyərləri necə tapmaq olar və ən əsası, NULL onların işinə necə təsir edir.
Əgər sən heç vaxt həyatında ən vacib şeyi axtarmısansa (məsələn, sevgi, arzu olunan iş və ya ən yaxşı pizza resepti), dərhal başa düşəcəksən ki, GREATEST() və LEAST() funksiyaları nə üçündür. Bu funksiyalar siyahıdakı şeylər arasında ən böyüyü və ya ən kiçiyini tapmağa kömək edir. Sadəcə pizza əvəzinə sən rəqəmlərlə, tarixlərlə, sətirlərlə və digər məlumatlarla PostgreSQL-də işləyirsən.
GREATEST()
GREATEST() verilmiş siyahıdan ən böyük dəyəri qaytarır.
Sintaksis:
GREATEST(value1, value2, ..., valueN)
LEAST()
LEAST() isə əksinə: ən kiçik dəyəri tapır.
Sintaksis:
LEAST(value1, value2, ..., valueN)
Nümunə:
Təsəvvür elə, bizdə students_scores adlı bir cədvəl var və burada tələbələrin üç imtahan üzrə balları saxlanılır:
| student_id | exam_1 | exam_2 | exam_3 |
|---|---|---|---|
| 1 | 85 | 90 | 82 |
| 2 | NULL | 76 | 89 |
| 3 | 94 | NULL | 88 |
GREATEST() və LEAST() istifadəsi:
SELECT
student_id,
GREATEST(exam_1, exam_2, exam_3) AS highest_score,
LEAST(exam_1, exam_2, exam_3) AS lowest_score
FROM students_scores;
Nəticə:
| student_id | highest_score | lowest_score |
|---|---|---|
| 1 | 90 | 82 |
| 2 | 89 | NULL |
| 3 | 94 | NULL |
NULL GREATEST() və LEAST()-ə necə təsir edir
İndi ən maraqlı yerə gəldik. Cədvəldəki dəyərlərlə yanaşı, NULL da ola bilər. Artıq bilirik ki, NULL — bu, məlumatın olmamasını və ya naməlum dəyəri göstərən bir mistik varlıqdır. Gəlin baxaq, əgər NULL GREATEST() və LEAST() funksiyalarına düşsə, PostgreSQL-də nə baş verir.
NULL-ın davranışı:
PostgreSQL-də GREATEST() və LEAST() funksiyalarının xüsusi davranışı var: onlar ən böyük və ya ən kiçik dəyəri tapanda NULL dəyərləri nəzərə almır. Vacibdir: Yeganə hal odur ki, əgər bütün arqumentlər NULL olsa, bu funksiyalar NULL qaytaracaq.
Nümunə:
SELECT
GREATEST(10, 20, NULL, 5) AS greatest_value,
LEAST(10, 20, NULL, 5) AS least_value;
Nəticə:
| greatest_value | least_value |
|---|---|
| 20 | 5 |
Gördüyün kimi, NULL sayılmadı və funksiyalar mövcud olan dəyərlərdən (10, 20, 5) ən böyüyü və ən kiçiyini qaytardı.
İndi isə bütün arqumentlər NULL olanda nə baş verir:
Nümunə:
SELECT
GREATEST(NULL, NULL) AS greatest_nulls,
LEAST(NULL, NULL) AS least_nulls;
Nəticə:
| greatest_nulls | least_nulls |
|---|---|
| NULL | NULL |
NULL ilə problemlərdən necə qaçmaq olar?
Baxmayaraq ki, PostgreSQL NULL-u default olaraq nəzərə almır, bəzən sənə başqa cür davranış lazım ola bilər. Məsələn, istəyirsən ki, NULL ən böyük/ən kiçik dəyəri tapanda konkret bir dəyər (məsələn, 0 və ya başqa default dəyər) kimi qəbul olunsun. Belə hallarda COALESCE() funksiyasından istifadə edə bilərsən.
COALESCE(arg1, arg2, ...) funksiyası siyahıdakı ilk NULL olmayan dəyəri qaytarır. Bu, GREATEST() və ya LEAST()-ə ötürməzdən əvvəl NULL-u mənalı bir dəyərlə əvəz etməyə imkan verir.
Nümunə 1: NULL-u 0 ilə əvəz etmək
Tutaq ki, istəyirik ki, NULL balı yoxdursa, bu 0 kimi qəbul olunsun. COALESCE() ilə default dəyər qoymaq olar.
Bizim ilkin cədvəlimiz belədir:
| student_id | exam_1 | exam_2 | exam_3 |
|---|---|---|---|
| 1 | 90 | 85 | 82 |
| 2 | NULL | 89 | NULL |
| 3 | NULL | NULL | 94 |
Sorgu:
SELECT
student_id,
GREATEST(
COALESCE(exam_1, 0),
COALESCE(exam_2, 0),
COALESCE(exam_3, 0)
) AS highest_score,
LEAST(
COALESCE(exam_1, 0),
COALESCE(exam_2, 0),
COALESCE(exam_3, 0)
) AS lowest_score
FROM students_scores;
Nəticə:
| student_id | highest_score | lowest_score |
|---|---|---|
| 1 | 90 | 82 |
| 2 | 89 | 0 |
| 3 | 94 | 0 |
Nümunə 2: NULL-u başqa sütundan olan dəyərlə əvəz etmək
Bəzən isə sabit dəyər (məsələn, 0) əvəzinə başqa sütundan olan dəyəri qoymaq lazımdır. Məsələn, əgər exam_3 yoxdursa, exam_1-in dəyərini istifadə etmək istəyirik.
SELECT
student_id,
GREATEST(
exam_1,
exam_2,
COALESCE(exam_3, exam_1)
) AS highest_score
FROM students_scores;
Tutaq ki, belə bir cədvəlimiz var:
| student_id | exam_1 | exam_2 | exam_3 |
|---|---|---|---|
| 1 | 90 | 85 | 82 |
| 2 | NULL | 89 | NULL |
| 3 | 70 | NULL | NULL |
Sorgunun nəticəsi:
| student_id | highest_score |
|---|---|
| 1 | 90 |
| 2 | 89 |
| 3 | 70 |
Praktik keislər
Keis 1: Maksimum endirimi tapmaq
| order_id | discount_1 | discount_2 | discount_3 |
|---|---|---|---|
| 101 | 5 | 10 | 7 |
| 102 | NULL | 3 | 8 |
| 103 | 15 | NULL | NULL |
| 104 | NULL | NULL | NULL |
Sən orders cədvəli ilə işləyirsən və hər sifariş üçün üç fərqli endirim növü ola bilər. Hər sifariş üçün bütün endirimlərdən maksimumunu tapmaq lazımdır.
SELECT
order_id,
GREATEST(discount_1, discount_2, discount_3) AS max_discount
FROM orders;
Nəticə:
| order_id | max_discount |
|---|---|
| 101 | 10 |
| 102 | 8 |
| 103 | 15 |
| 104 | NULL |
Keis 2: Məhsulun minimum qiymətini tapmaq
products cədvəlində məhsulların üç valyutada (USD, EUR, GBP) qiymətləri saxlanılır. Sənin tapşırığın — hər məhsul üçün minimum qiyməti tapmaqdır.
| product_id | price_usd | price_eur | price_gbp |
|---|---|---|---|
| 1 | 100 | 95 | 80 |
| 2 | NULL | 150 | 140 |
| 3 | 200 | NULL | NULL |
| 4 | NULL | NULL | NULL |
SELECT
product_id,
LEAST(price_usd, price_eur, price_gbp) AS lowest_price
FROM products;
| product_id | lowest_price |
|---|---|
| 1 | 80 |
| 2 | 140 |
| 3 | 200 |
| 4 | NULL |
Əgər bütün qiymətlər NULL-dursa, nəticə də NULL olacaq
GREATEST() və LEAST() istifadə edəndə tipik səhvlər
Səhv 1: NULL səbəbindən gözlənilməz nəticə.
Leksiyada artıq ətraflı danışdıq ki, NULL PostgreSQL-də GREATEST() və LEAST()-ə necə təsir edir. Əsas səhv odur ki, başqa DBMS-lərdə NULL bir dəfə olsa, bütün nəticəni "zəhərləyir", buna öyrəşən istifadəçilər PostgreSQL-də də eyni davranışı gözləyirlər.
Səhv necə görünür: Sən səhvən düşünə bilərsən ki, arqumentlər arasında NULL varsa, funksiya həmişə NULL qaytaracaq. Nəticədə, bütün arqumentlərə COALESCE() tətbiq edirsən, halbuki sənin ssenarində NULL sadəcə nəzərə alınmaya bilərdi və bu, sorğunu lazımsız şəkildə çətinləşdirir və yavaşladır.
Səhv 2: GREATEST() və LEAST() funksiyalarını uyğun olmayan tiplərlə istifadə etmək.
GREATEST() və LEAST() funksiyaları eyni data type-da və ya bir-birinə avtomatik çevrilə bilən tiplərdə dəyərləri müqayisə etmək üçündür. Tamamilə fərqli, uyğun olmayan tipləri müqayisə etməyə çalışsan, səhv alacaqsan.
Səhv necə görünür: Data type uyğun gəlmədiyini göstərən error mesajı alacaqsan.
GO TO FULL VERSION