JavaRush /Курси /SQL SELF /Порівняння та фільтрація масивів: =, @>, <@, &&...

Порівняння та фільтрація масивів: =, @>, <@, &&

SQL SELF
Рівень 36 , Лекція 1
Відкрита

Іноді виникають ситуації, коли треба зрозуміти, чи міститься одна множина значень в іншій, чи перетинаються вони, чи рівні вони або є підмножинами одна одної. Наприклад:

  • Чи має користувач доступ до певних категорій?
  • Які товари мають спільні теги?
  • Які масиви містять усі перелічені значення?

Ці задачі вирішуються за допомогою операторів порівняння масивів у PostgreSQL: =, @>, <@ і &&. Зараз розглянемо кожен із цих операторів на прикладах.

= — Порівняння масивів на рівність

Цей оператор використовується, щоб перевірити, чи ідентичні два масиви. Умова поверне TRUE, якщо обидва масиви мають однакову довжину й однаковий набір елементів у точно такому ж порядку.

Приклад:

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

Особливість: порядок елементів має значення. Масив [1, 2, 3] не дорівнює [3, 2, 1].

@> — Масив містить інший масив

Цей оператор перевіряє, чи містить масив усі елементи іншого масиву (незалежно від порядку). Часто використовується для задач, де треба впевнитися, що всі потрібні елементи присутні.

Приклад:

SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2] AS contains;  -- TRUE
SELECT ARRAY[1, 2, 3] @> ARRAY[4] AS contains;     -- FALSE

Корисний сценарій: перевірка прав доступу. Наприклад, ти хочеш впевнитися, що певна роль включає всі необхідні дозволи.

<@ — Масив є підмножиною іншого масиву

Протилежність оператора @>. Перевіряє, чи міститься масив повністю в іншому масиві.

Приклад:

SELECT ARRAY[1, 2] <@ ARRAY[1, 2, 3] AS is_subset;  -- TRUE
SELECT ARRAY[4] <@ ARRAY[1, 2, 3] AS is_subset;     -- FALSE

Корисний сценарій: коли треба перевірити, чи має конкретний рядок таблиці всі потрібні мітки або категорії.

&& — Перетин масивів

Цей оператор перевіряє, чи перетинаються два масиви, тобто чи мають вони хоча б один спільний елемент.

Приклад:

SELECT ARRAY[1, 2, 3] && ARRAY[3, 4, 5] AS intersects;  -- TRUE
SELECT ARRAY[1, 2, 3] && ARRAY[6, 7, 8] AS intersects;  -- FALSE

Корисний сценарій: пошук товарів або записів, які мають спільні категорії чи характеристики.

Використання операторів у фільтрації даних

Давай застосуємо ці оператори для фільтрації даних у таблиці. Наприклад, у нас є таблиця products зі стовпцем tags, який містить масив тегів для кожного товару.

Приклад таблиці products

id name tags
1 "Product A" {electronics, sale}
2 "Product B" {home, sale}
3 "Product C" {electronics, new}
4 "Product D" {home, garden}

Знайдемо всі товари, які мають тег electronics.

SELECT *
FROM products
WHERE tags @> ARRAY['electronics'];

Результат:

id name tags
1 "Product A" {electronics, sale}
3 "Product C" {electronics, new}

Хочемо знайти товари, у яких теги рівно {home, sale}.

SELECT *
FROM products
WHERE tags = ARRAY['home', 'sale'];

Результат:

id name tags
2 "Product B" {home, sale}

А тепер давай

знайдемо товари, у яких є хоча б один із тегів {sale, new}.
SELECT *
FROM products
WHERE tags && ARRAY['sale', 'new'];

Результат:

id name tags
1 "Product A" {electronics, sale}
2 "Product B" {home, sale}
3 "Product C" {electronics, new}

Шукаємо товари, де теги точно обмежуються {home, garden}.

SELECT *
FROM products
WHERE tags <@ ARRAY['home', 'garden'];

Результат:

id name tags
4 "Product D" {home, garden}

Приклад: перевірка вмісту списків з CASE

Можна поєднати порівняння масивів з умовними виразами. Наприклад, зробимо запит, який позначає товари, що містять тег sale, як "Знижка", а інші — як "Без знижки":

SELECT name,
       CASE
         WHEN tags @> ARRAY['sale'] THEN 'Знижка'
         ELSE 'Без знижки'
       END AS discount_status
FROM products;

Результат:

name discount_status
"Product A" Знижка
"Product B" Знижка
"Product C" Без знижки
"Product D" Без знижки

Типові помилки та як їх уникнути

Помилка: неправильне використання порядку елементів в операторі =. Пам’ятай, що = вимагає точного співпадіння порядку елементів. Якщо порядок не важливий, використовуй @> або &&.

Помилка: невідповідність типів даних. Масиви мають бути одного типу. Наприклад, ARRAY['1', '2'] не дорівнює ARRAY[1, 2], бо перший масив строковий, а другий — числовий. Завжди перевіряй типи перед порівнянням.

Помилка: відсутність індексів. Якщо ти часто фільтруєш рядки по масивах, обов’язково створи індекси (GIN) для підвищення продуктивності.

Ці оператори дозволяють реалізувати потужну фільтрацію та порівняння даних, які часто зустрічаються в реальних проектах: від аналізу тегів товарів до керування правами доступу. Використовуючи їх ефективно, ти зможеш спростити складні задачі й оптимізувати роботу своїх запитів.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ