A veces te encuentras con situaciones donde necesitas saber si un conjunto de valores está contenido en otro, si se cruzan, si son iguales o si uno es subconjunto del otro. Por ejemplo:
- ¿Tiene el usuario acceso a ciertas categorías?
- ¿Qué productos tienen tags en común?
- ¿Qué arrays contienen todos los valores listados?
Estas tareas se resuelven usando los operadores de comparación de arrays en PostgreSQL: =, @>, <@ y &&. Vamos a sumergirnos en cada uno de estos operadores y verlos con ejemplos.
= — Comparar arrays por igualdad
Este operador se usa para comprobar si dos arrays son idénticos. La condición devuelve TRUE si ambos arrays tienen la misma longitud y el mismo conjunto de elementos en exactamente el mismo orden.
Ejemplo:
SELECT ARRAY[1, 2, 3] = ARRAY[1, 2, 3] AS son_iguales; -- TRUE
SELECT ARRAY[1, 2, 3] = ARRAY[3, 2, 1] AS son_iguales; -- FALSE
Importante: el orden de los elementos importa. El array [1, 2, 3] no es igual a [3, 2, 1].
@> — Un array contiene a otro array
Este operador comprueba si un array contiene todos los elementos de otro array (sin importar el orden). Se usa mucho cuando necesitas asegurarte de que todos los elementos buscados están presentes.
Ejemplo:
SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2] AS contiene; -- TRUE
SELECT ARRAY[1, 2, 3] @> ARRAY[4] AS contiene; -- FALSE
Escenario útil: comprobación de permisos de acceso. Por ejemplo, quieres asegurarte de que un rol incluye todos los permisos necesarios.
<@ — Un array es subconjunto de otro array
Lo contrario del operador @>. Comprueba si un array está completamente contenido en otro array.
Ejemplo:
SELECT ARRAY[1, 2] <@ ARRAY[1, 2, 3] AS es_subconjunto; -- TRUE
SELECT ARRAY[4] <@ ARRAY[1, 2, 3] AS es_subconjunto; -- FALSE
Escenario útil: cuando necesitas comprobar si una fila de la tabla tiene todas las etiquetas o categorías necesarias.
&& — Intersección de arrays
Este operador comprueba si dos arrays se cruzan, es decir, si tienen al menos un elemento en común.
Ejemplo:
SELECT ARRAY[1, 2, 3] && ARRAY[3, 4, 5] AS se_cruzan; -- TRUE
SELECT ARRAY[1, 2, 3] && ARRAY[6, 7, 8] AS se_cruzan; -- FALSE
Escenario útil: buscar productos o registros que tengan categorías o características en común.
Usando los operadores para filtrar datos
Vamos a aplicar estos operadores para filtrar datos en una tabla. Por ejemplo, tenemos una tabla products con una columna tags que contiene un array de tags para cada producto.
Ejemplo de la tabla 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 a buscar todos los productos que tengan el tag electronics.
SELECT *
FROM products
WHERE tags @> ARRAY['electronics'];
Resultado:
| id | name | tags |
|---|---|---|
| 1 | "Product A" | {electronics, sale} |
| 3 | "Product C" | {electronics, new} |
Queremos encontrar productos cuyos tags sean exactamente {home, sale}.
SELECT *
FROM products
WHERE tags = ARRAY['home', 'sale'];
Resultado:
| id | name | tags |
|---|---|---|
| 2 | "Product B" | {home, sale} |
Ahora vamos a
buscar productos que tengan al menos uno de los 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} |
Buscamos productos donde los tags sean exactamente {home, garden}.
SELECT *
FROM products
WHERE tags <@ ARRAY['home', 'garden'];
Resultado:
| id | name | tags |
|---|---|---|
| 4 | "Product D" | {home, garden} |
Ejemplo: comprobando el contenido de arrays con CASE
Podemos combinar la comparación de arrays con expresiones condicionales. Por ejemplo, vamos a crear una consulta que marque los productos que contienen el tag sale como "Descuento", y los demás como "Sin descuento":
SELECT name,
CASE
WHEN tags @> ARRAY['sale'] THEN 'Descuento'
ELSE 'Sin descuento'
END AS estado_descuento
FROM products;
Resultado:
| name | estado_descuento |
|---|---|
| "Product A" | Descuento |
| "Product B" | Descuento |
| "Product C" | Sin descuento |
| "Product D" | Sin descuento |
Errores típicos y cómo evitarlos
Error: mal uso del orden de los elementos con el operador =. Recuerda que = requiere que el orden de los elementos sea exactamente igual. Si el orden no importa, usa @> o &&.
Error: tipos de datos incompatibles. Los arrays deben ser del mismo tipo. Por ejemplo, ARRAY['1', '2'] no es igual a ARRAY[1, 2], porque el primero es de strings y el segundo es numérico. Siempre revisa los tipos antes de comparar.
Error: falta de índices. Si filtras filas por arrays a menudo, asegúrate de crear índices (GIN) para mejorar el rendimiento.
Estos operadores te permiten hacer filtrados y comparaciones potentes de datos, algo que te vas a encontrar mucho en proyectos reales: desde analizar tags de productos hasta gestionar permisos de acceso. Si los usas bien, vas a simplificar tareas complejas y optimizar tus consultas.
GO TO FULL VERSION