Bəzən elə situasiyalar olur ki, bir dəyər toplusunun başqa bir topluda olub-olmadığını, kəsişib-kəsişmədiyini, tam eyni olub-olmadığını və ya birinin digərinin alt toplusu olub-olmadığını yoxlamaq lazımdır. Məsələn:
- İstifadəçinin müəyyən kateqoriyalara çıxışı var?
- Hansı məhsulların ortaq tag-ları var?
- Hansı massivlər sadalanan bütün dəyərləri saxlayır?
Bu məsələləri PostgreSQL-də massivlərin müqayisə operatorları ilə həll eləmək olur: =, @>, <@ və &&. Gəlin hər bir operatora baxaq və nümunələrlə izah edək.
= — Massivlərin bərabərliyinin yoxlanması
Bu operator iki massiv tam eyni olduqda istifadə olunur. Şərt TRUE qaytaracaq, əgər hər iki massiv eyni uzunluqdadırsa və elementləri tam eyni ardıcıllıqla yerləşibsə.
Nümunə:
SELECT ARRAY[1, 2, 3] = ARRAY[1, 2, 3] AS are_equal; -- TRUE
SELECT ARRAY[1, 2, 3] = ARRAY[3, 2, 1] AS are_equal; -- FALSE
Xüsusiyyət: elementlərin sırası vacibdir. [1, 2, 3] massiv [3, 2, 1] massivinə bərabər deyil.
@> — Massiv başqa bir massivə daxildirmi?
Bu operator yoxlayır ki, massiv digər massivdəki bütün elementləri saxlayırmı (sıra önəmli deyil). Çox vaxt lazım olur ki, bütün axtarılan elementlər mövcuddurmu, onu yoxlamaq üçün istifadə olunur.
Nümunə:
SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2] AS contains; -- TRUE
SELECT ARRAY[1, 2, 3] @> ARRAY[4] AS contains; -- FALSE
Faydalı situasiya: access hüquqlarının yoxlanması. Məsələn, hansısa rolun bütün lazım olan icazələri ehtiva edib-etmədiyini yoxlamaq istəyirsən.
<@ — Massiv başqa massivdə alt topludur
@> operatorunun əksidir. Yoxlayır ki, massiv tamamilə başqa massivdə mövcuddurmu.
Nümunə:
SELECT ARRAY[1, 2] <@ ARRAY[1, 2, 3] AS is_subset; -- TRUE
SELECT ARRAY[4] <@ ARRAY[1, 2, 3] AS is_subset; -- FALSE
Faydalı situasiya: məsələn, hansısa cədvəlin sətrində bütün lazım olan tag-lar və ya kateqoriyalar var?
&& — Massivlərin kəsişməsi
Bu operator yoxlayır ki, iki massivdə heç olmasa bir ortaq element var?
Nümunə:
SELECT ARRAY[1, 2, 3] && ARRAY[3, 4, 5] AS intersects; -- TRUE
SELECT ARRAY[1, 2, 3] && ARRAY[6, 7, 8] AS intersects; -- FALSE
Faydalı situasiya: ortaq kateqoriyaları və ya xüsusiyyətləri olan məhsulları və ya qeydləri tapmaq.
Operatorların data filtrasiyasında istifadəsi
Gəlin bu operatorları cədvəldə data filtrasiyası üçün tətbiq edək. Məsələn, products adlı cədvəlimiz var və tags sütununda hər məhsul üçün massiv şəklində tag-lar saxlanılır.
products cədvəlinin nümunəsi
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 2 | "Product B" | {home, sale} |
| 3 | "Product C" | {electronics, new} |
| 4 | "Product D" | {home, garden} |
Gəlin bütün electronics tag-ı olan məhsulları tapaq.
SELECT *
FROM products
WHERE tags @> ARRAY['electronics'];
Nəticə:
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 3 | "Product C" | {electronics, new} |
Tag-ları tam olaraq {home, sale} olan məhsulları tapmaq istəyirik.
SELECT *
FROM products
WHERE tags = ARRAY['home', 'sale'];
Nəticə:
| id | name | tags |
|---|---|---|
| 2 | "Product B" | {home, sale} |
İndi isə
məhsulların tag-larında ən azı biri {sale, new} olanları tapırıq.SELECT *
FROM products
WHERE tags && ARRAY['sale', 'new'];
Nəticə:
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 2 | "Product B" | {home, sale} |
| 3 | "Product C" | {electronics, new} |
Tag-ları tam olaraq {home, garden} ilə məhdudlaşan məhsulları tapırıq.
SELECT *
FROM products
WHERE tags <@ ARRAY['home', 'garden'];
Nəticə:
| id | name | tags |
|---|---|---|
| 4 | "Product D" | {home, garden} |
Nümunə: CASE ilə massivlərin tərkibini yoxlamaq
Massivlərin müqayisəsini şərtli ifadələrlə birləşdirə bilərik. Məsələn, bir sorğu yazaq ki, sale tag-ı olan məhsulları "Endirim", digərlərini isə "Endirim yoxdur" kimi işarələsin:
SELECT name,
CASE
WHEN tags @> ARRAY['sale'] THEN 'Endirim'
ELSE 'Endirim yoxdur'
END AS discount_status
FROM products;
Nəticə:
| name | discount_status |
|---|---|
| "Product A" | Endirim |
| "Product B" | Endirim |
| "Product C" | Endirim yoxdur |
| "Product D" | Endirim yoxdur |
Tipik səhvlər və onların qarşısını almaq
Səhv: = operatorunda elementlərin sırasını səhv istifadə etmək. Unutma ki, = operatoru elementlərin tam eyni sırada olmasını tələb edir. Əgər sıra önəmli deyilsə, @> və ya && istifadə elə.
Səhv: data tiplərinin uyğun gəlməməsi. Massivlər eyni tipdə olmalıdır. Məsələn, ARRAY['1', '2'] ARRAY[1, 2]-yə bərabər deyil, çünki birincisi string, ikincisi isə rəqəmdir. Müqayisədən əvvəl həmişə tipləri yoxla.
Səhv: indekslərin olmaması. Əgər tez-tez massivlər üzrə filtrasiya edirsənsə, performansı artırmaq üçün mütləq GIN indeksləri yarat.
Bu operatorlar real layihələrdə tez-tez rast gəlinən data filtrasiyası və müqayisəsi üçün güclü imkanlar verir: məhsul tag-larının analizindən tutmuş access hüquqlarının idarə olunmasına qədər. Onlardan düzgün istifadə eləsən, çətin məsələləri asanlaşdırıb sorğularını optimallaşdıra bilərsən.
GO TO FULL VERSION