Massivlər tez-tez bir sütunda bir neçə dəyəri saxlamaq üçün istifadə olunur — məsələn, teqlər, nömrələr, rollar və ya üstünlüklər. Amma necə bilək ki, massivdə bizə lazım olan dəyər var, ya da əksinə — bütün elementlər müəyyən şərtə uyğundur? PostgreSQL belə yoxlamalar üçün rahat vasitələr verir: ANY, ALL və array_contains(). Gəlin hər birini bir-bir baxaq.
ANY nədir?
Təsəvvür elə, səndə bir massiv var, içində bir neçə dəyər yazılıb, məsələn, məhsul ID-ləri, telefon nömrələri və ya hobbilər siyahısı. Tez-tez belə bir tapşırıq çıxır: massivdə müəyyən bir dəyər var, ya yox? Bax, burada ANY operatoru köməyə gəlir. O, yoxlamağa imkan verir ki, "axtardığımız obyekt" massivdə var, ya yox.
ANY sintaksisi
SELECT *
FROM your_table
WHERE value = ANY(array_column);
Burada:
array_column— yoxladığımız massivdir.value— massivdə axtardığımız dəyərdir.
ANY istifadəsinə nümunə
Tutaq ki, bizdə belə bir students cədvəli var:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {oxumaq, üzgüçülük, şahmat} |
| 2 | Eva | {musiqi, oxumaq, idman} |
| 3 | Alex | {rəsm, musiqi} |
| 4 | Maria | {şahmat, futbol} |
Bizə maraqlıdır, hansı tələbələrin hobbiləri arasında üzgüçülük var. Sorğu belə olacaq:
SELECT *
FROM students
WHERE 'üzgüçülük' = ANY(hobbies);
Nəticə:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {oxumaq, üzgüçülük, şahmat} |
Qısaca desək, ANY yoxlayır: "Bu massivdə bu dəyər var?"
Etibar et, amma hamısını yoxla! ALL istifadə edirik
İndi əks vəziyyəti təsəvvür elə: sənə lazımdır ki, massivdəki bütün elementlər müəyyən qaydaya uyğun olsun. Bunun üçün PostgreSQL ALL operatorunu təklif edir. Onun köməyi ilə yoxlaya bilərsən ki, massivdəki bütün elementlər, məsələn, verilmiş dəyərə bərabərdir, müəyyən bir ədəddən böyükdür və ya başqa bir məntiqi şərtə uyğundur.
ALL sintaksisi
SELECT *
FROM your_table
WHERE value < ALL(array_column);
Burada:
array_column— yoxladığımız massivdir.value < ALL(...)o deməkdir ki, bütün massiv elementləri bu dəyərdən böyük olmalıdır.
Yenə students cədvəlinə qayıdaq. Tutaq ki, istəyirik tələbələri tapaq ki, onların bütün hobbiləri "o" hərfi ilə başlayır. Sorğu:
SELECT *
FROM students
WHERE 'oxumaq' = ALL(hobbies);
Nəticə boş olacaq, çünki heç kimin bütün hobbiləri "oxumaq" sözünə bərabər deyil. Daha aydın (və işləyən) nümunə üçün gəlin ədədi verilənlərə baxaq.
Tutaq ki, belə bir orders cədvəlimiz var:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
| 3 | Alex | {500, 600, 700} |
Bütün mövqeləri 400-dən ucuz olan sifarişləri tapmaq:
SELECT *
FROM orders
WHERE 400 > ALL(prices);
Nəticə:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
Massivin tərkibinə görə sətirlərin filtrasiyası
Biz massivdə məlumat axtarışı üçün əsas funksiyaları və operatorları keçdik, bəs bunlar praktikada necə işləyir? Gəlin bir neçə istifadə nümunəsinə baxaq.
Nümunə 1: Hobbilərindən ən azı biri musiqi olan tələbələri tapmaq
İlkin cədvəl:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {oxumaq, musiqi, qaçış} |
| 2 | Eva | {rəsm, üzgüçülük} |
| 3 | Maria | {musiqi, boks} |
| 4 | Alex | {futbol, boks, stolüstü} |
SELECT *
FROM students
WHERE 'musiqi' = ANY(hobbies);
Nəticə:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {oxumaq, musiqi, qaçış} |
| 3 | Maria | {musiqi, boks} |
Nümunə 2: Bütün mövqeləri 100-dən böyük olan sifarişləri tapmaq
İlkin orders cədvəli:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 2 | Eva | {50, 120, 130} |
| 3 | Maria | {200, 250, 100} |
| 4 | Alex | {110, 115, 120} |
SELECT *
FROM orders
WHERE 100 < ALL(prices);
Nəticə:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 4 | Alex | {110, 115, 120} |
Tipik səhvlər və onlardan necə qaçmaq olar
Massivlərlə işləyəndə, xüsusilə məlumat axtaranda, bir neçə "tələ" var ki, diqqətli olmaq lazımdır.
Səhv: ANY və ya ALL yanlış istifadə olunur. Məsələn, operatorları səhv salanda gözlənilməz nəticələr ala bilərsən.
-- Yanlış variant:
SELECT *
FROM students
WHERE hobbies = ANY('oxumaq');
Bu nümunədə səhv ondadır ki, hobbies massivdir, 'oxumaq' isə sətirdir. Məhz massiv ANY ilə yoxlanmalıdır, tərsinə yox.
Səhv: Massivlərdə indeksləşmə 1-dən başlayır, 0-dan yox. Əgər massivləri başqa funksiyalarda istifadə edirsənsə və ya elementləri əl ilə çıxarırsansa, PostgreSQL-in bu özəlliyini unutma.
Səhv: İndeksləşmə yoxdur. Əgər massivlərdə tez-tez axtarış əməliyyatları (ANY, ALL) aparırsansa, indeksləşmə sorğuları xeyli sürətləndirə bilər.
GO TO FULL VERSION