jsonb
en Postgres 9.4 o posterior
Considere el jsonb
tipo de datos en Postgres 9.4 - 'b' para 'binario'. Entre otras cosas, hay un operador de igualdad =
parajsonb
. La mayoría de la gente querrá cambiar.
Blog de Depesz sobre jsonb.
json
No hay un =
operador definido para el tipo de datos json
, porque no hay un método bien definido para establecer la igualdad de los json
valores completos . Pero mira abajo.
Usted podría emitir a text
y luego usar el =
operador. Esto es breve, pero solo funciona si su representación de texto coincide. Inherentemente poco confiable, excepto en casos de esquina. Ver:
O puede unnest
la matriz y usar el ->>
operador para ... get JSON object field as text
y comparar campos individuales.
Mesa de prueba
2 filas: la primera como en la pregunta, la segunda con valores simples.
CREATE TABLE tbl (
tbl_id int PRIMARY KEY
, jar json[]
);
INSERT INTO t VALUES
(1, '{"{\"value\" : \"03334/254146\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f5\"}"
,"{\"value\" : \"03334/254147\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f6\"}"
,"{\"value\" : \"03334/254148\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f7\"}"}')
, (2, '{"{\"value\" : \"a\", \"typeId\" : \"x\"}"
,"{\"value\" : \"b\", \"typeId\" : \"y\"}"
,"{\"value\" : \"c\", \"typeId\" : \"z\"}"}');
Población
Demostración 1: se puede usar array_remove()
con text
representaciones (poco confiable).
SELECT tbl_id
, jar, array_length(jar, 1) AS jar_len
, jar::text[] AS t, array_length(jar::text[], 1) AS t_len
, array_remove(jar::text[], '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-f6"}'::text) AS t_result
, array_remove(jar::text[], '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-f6"}'::text)::json[] AS j_result
FROM tbl;
Demostración 2: anule la matriz y los campos de prueba de elementos individuales.
SELECT tbl_id, array_agg(j) AS j_new
FROM tbl, unnest(jar) AS j -- LATERAL JOIN
WHERE j->>'value' <> '03334/254146'
AND j->>'typeId' <> 'ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf5'
GROUP BY 1;
Demo 3: prueba alternativa con tipo de fila.
SELECT tbl_id, array_agg(j) AS j_new
FROM tbl, unnest(jar) AS j -- LATERAL JOIN
WHERE (j->>'value', j->>'typeId') NOT IN (
('03334/254146', 'ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf5')
,('a', 'x')
)
GROUP BY 1;
UPDATE
de acuerdo a lo pedido
Finalmente, así es como podría implementar su UPDATE
:
UPDATE tbl t
SET jar = j.jar
FROM tbl t1
CROSS JOIN LATERAL (
SELECT ARRAY(
SELECT j
FROM unnest(t1.jar) AS j -- LATERAL JOIN
WHERE j->>'value' <> 'a'
AND j->>'typeId' <> 'x'
) AS jar
) j
WHERE t1.tbl_id = 2 -- only relevant rows
AND t1.tbl_id = t.tbl_id;
db <> violín aquí
Sobre lo implícito LATERAL JOIN
:
Acerca de la anulación de matrices:
Diseño DB
Para simplificar su situación, considere un esquema normalizado : una tabla separada para los json
valores (en lugar de la columna de matriz), unida en una relación: 1 con la tabla principal.