jsonb
no Postgres 9.4 ou posterior
Considere o jsonb
tipo de dados no Postgres 9.4 - 'b' para 'binário'. Entre outras coisas, existe um operador de igualdade =
parajsonb
. A maioria das pessoas vai querer mudar.
Blog do Depesz sobre jsonb.
json
Não há =
operador definido para o tipo de dados json
, porque não existe um método bem definido para estabelecer igualdade para json
valores inteiros . Mas veja abaixo.
Você pode transmitir text
e usar o =
operador. Isso é curto, mas só funciona se sua representação de texto coincidir. Inerentemente não confiável, exceto nos casos de canto. Vejo:
Ou você pode fazer unnest
a matriz e usar o ->>
operador para .. get JSON object field as text
e comparar campos individuais.
Tabela de teste
2 linhas: a primeira como na pergunta, a segunda com 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\"}"}');
Demonstrações
Demo 1: você pode usar array_remove()
com text
representações (não confiável).
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;
Demo 2: anule a matriz e teste os campos de elementos individuais.
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: teste alternativo com o tipo de linha.
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
como pedido
Por fim, é assim que você pode implementar o seu 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 <> mexer aqui
Sobre o implícito LATERAL JOIN
:
Sobre matrizes desinteressantes:
Design do banco de dados
Para simplificar sua situação, considere um esquema normalizado : uma tabela separada para os json
valores (em vez da coluna da matriz), unida em um relacionamento: 1 à tabela principal.
jsonb
. Espero que você ame. Adicionado um capítulo com links.