Às vezes rolam uns cenários em que tu precisa sacar se um conjunto de valores tá dentro de outro, se eles se cruzam, se são iguais ou se um é subconjunto do outro. Tipo assim:
- O usuário tem acesso a certas categorias?
- Quais produtos têm tags em comum?
- Quais arrays contêm todos os valores listados?
Essas paradas tu resolve usando os operadores de comparação de arrays no PostgreSQL: =, @>, <@ e &&. Bora ver cada um deles com exemplos.
= — Comparando arrays pra ver se são iguais
Esse operador serve pra checar se dois arrays são idênticos. A condição retorna TRUE se os dois arrays tiverem o mesmo tamanho e o mesmo conjunto de elementos na mesma ordem, certinho.
Exemplo:
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
Detalhe: a ordem dos elementos importa. O array [1, 2, 3] não é igual a [3, 2, 1].
@> — Array contém outro array
Esse operador checa se um array contém todos os elementos de outro array (não importa a ordem). É muito usado quando tu precisa garantir que todos os itens procurados estão presentes.
Exemplo:
SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2] AS contains; -- TRUE
SELECT ARRAY[1, 2, 3] @> ARRAY[4] AS contains; -- FALSE
Cenário útil: checar permissões de acesso. Tipo, tu quer garantir que um certo papel tem todas as permissões necessárias.
<@ — Array é subconjunto de outro array
É o contrário do operador @>. Ele verifica se um array tá totalmente contido em outro array.
Exemplo:
SELECT ARRAY[1, 2] <@ ARRAY[1, 2, 3] AS is_subset; -- TRUE
SELECT ARRAY[4] <@ ARRAY[1, 2, 3] AS is_subset; -- FALSE
Cenário útil: quando tu precisa ver se uma linha da tabela tem todas as tags ou categorias necessárias.
&& — Interseção de arrays
Esse operador checa se dois arrays têm pelo menos um elemento em comum.
Exemplo:
SELECT ARRAY[1, 2, 3] && ARRAY[3, 4, 5] AS intersects; -- TRUE
SELECT ARRAY[1, 2, 3] && ARRAY[6, 7, 8] AS intersects; -- FALSE
Cenário útil: buscar produtos ou registros que tenham categorias ou características em comum.
Usando os operadores pra filtrar dados
Bora aplicar esses operadores pra filtrar dados numa tabela. Imagina que a gente tem uma tabela products com uma coluna tags que guarda um array de tags pra cada produto.
Exemplo da tabela products
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 2 | "Product B" | {home, sale} |
| 3 | "Product C" | {electronics, new} |
| 4 | "Product D" | {home, garden} |
Vamos achar todos os produtos que têm a tag electronics.
SELECT *
FROM products
WHERE tags @> ARRAY['electronics'];
Resultado:
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 3 | "Product C" | {electronics, new} |
Agora vamos achar produtos cujas tags são exatamente {home, sale}.
SELECT *
FROM products
WHERE tags = ARRAY['home', 'sale'];
Resultado:
| id | name | tags |
|---|---|---|
| 2 | "Product B" | {home, sale} |
Agora bora
achar produtos que tenham pelo menos uma das tags {sale, new}.SELECT *
FROM products
WHERE tags && ARRAY['sale', 'new'];
Resultado:
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 2 | "Product B" | {home, sale} |
| 3 | "Product C" | {electronics, new} |
Agora vamos buscar produtos cujas tags são exatamente {home, garden}.
SELECT *
FROM products
WHERE tags <@ ARRAY['home', 'garden'];
Resultado:
| id | name | tags |
|---|---|---|
| 4 | "Product D" | {home, garden} |
Exemplo: checando conteúdo de listas com CASE
Dá pra juntar comparação de arrays com expressões condicionais. Por exemplo, vamos criar uma query que marca produtos que têm a tag sale como "Desconto", e os outros como "Sem desconto":
SELECT name,
CASE
WHEN tags @> ARRAY['sale'] THEN 'Desconto'
ELSE 'Sem desconto'
END AS discount_status
FROM products;
Resultado:
| name | discount_status |
|---|---|
| "Product A" | Desconto |
| "Product B" | Desconto |
| "Product C" | Sem desconto |
| "Product D" | Sem desconto |
Erros comuns e como evitar
Erro: usar ordem errada dos elementos com o operador =. Lembra que o = exige que a ordem dos elementos seja igualzinha. Se a ordem não importa, usa @> ou &&.
Erro: tipos de dados diferentes. Os arrays precisam ser do mesmo tipo. Por exemplo, ARRAY['1', '2'] não é igual a ARRAY[1, 2], porque o primeiro é array de string e o segundo é numérico. Sempre confere os tipos antes de comparar.
Erro: falta de índices. Se tu filtra muito por arrays, cria índices (GIN) pra melhorar a performance.
Esses operadores deixam tua filtragem e comparação de dados muito mais poderosa, coisa que aparece direto em projetos reais: desde análise de tags de produtos até controle de permissões de acesso. Usando eles direito, tu simplifica tarefas complicadas e ainda otimiza tuas queries.
GO TO FULL VERSION