CodeGym /Kurslar /SQL SELF /Massivlərin müqayisəsi və filtrasiya: =, @>, <@, &a...

Massivlərin müqayisəsi və filtrasiya: =, @>, <@, &&

SQL SELF
Səviyyə , Dərs
Mövcuddur

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: =, @>, <@&&. 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.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION