[
{
"id": 1,
"columns": [
{
"id": 16,
"expression": "foo"
},
{
"id": 12,
"expression": "bar"
}
]
},
{
"id": 2,
"columns": [
{
"id": 11,
"expression": "baz"
},
{
"id": 8,
"expression": "foobar"
}
]
}
]
Eu tenho uma tabela onde uma das colunas é uma matriz JSON de elementos. Acima, você pode ver como pode ser o valor desse campo.
A ideia é filtrar as linhas das tabelas com base no valor do expression
campo. Por exemplo, posso querer deixar apenas as linhas onde há uma coluna onde expression
equals foo
.
Minha primeira ideia foi usar json_array_elements()
várias vezes e, em seguida, escrever uma WHERE EXISTS(SELECT true FROM ...)
cláusula, mas isso resulta em duplicatas de linha. Além disso, minhas tentativas de combinar vários json_array_elements
nem sempre funcionam da maneira que eu esperava.
Funcionaria se eu pudesse, de alguma forma, nivelar todos os itens para que houvesse uma grande lista de expression
valores para cada linha. Infelizmente, não tenho certeza se existe uma maneira conveniente de fazer isso com essa estrutura aninhada.
ATUALIZAÇÃO: corrigido o objeto JSON
Minha tabela está assim:
id | description | | tables
1 | sample_description | <sample_above>
O resultado desejado é manter as linhas onde existe um item no columns
campo entre os itens deste tables
array json de forma que o expression
valor seja igual<some_value>
O WHERE EXISTS com json_array_elements certamente funcionaria e não geraria linhas duplicadas quando feito corretamente. Mas também não pode se beneficiar do índice gin na coluna json. Seria melhor fazê-lo da maneira que puder, como esse uso do operador de contenção.
Também funcionará com ANY, embora seja bastante detalhado:
Um exemplo do WHERE EXISTS funcionando, mas abaixo do ideal: