Іноді виникають ситуації, коли треба зрозуміти, чи міститься одна множина значень в іншій, чи перетинаються вони, чи рівні вони або є підмножинами одна одної. Наприклад:
- Чи має користувач доступ до певних категорій?
- Які товари мають спільні теги?
- Які масиви містять усі перелічені значення?
Ці задачі вирішуються за допомогою операторів порівняння масивів у 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) для підвищення продуктивності.
Ці оператори дозволяють реалізувати потужну фільтрацію та порівняння даних, які часто зустрічаються в реальних проектах: від аналізу тегів товарів до керування правами доступу. Використовуючи їх ефективно, ти зможеш спростити складні задачі й оптимізувати роботу своїх запитів.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ