Eu tenho uma tabela, persons
que contém duas colunas, uma id
e uma data
coluna baseada em JSONB (esta tabela foi criada apenas para fins de demonstração para brincar com o suporte a JSON do PostgreSQL).
Agora, suponha que ele contenha dois registros:
1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }
Agora, suponho que eu queira obter o nome de todas as pessoas com mais de 25 anos. O que tentei é:
select data->'name' as name from persons where data->'age' > 25
Infelizmente, isso resulta em um erro. Eu posso resolvê-lo usando em ->>
vez de ->
, mas as comparações não funcionam mais como o esperado, pois não são comparados os números, mas suas representações como seqüências de caracteres:
select data->'name' as name from persons where data->>'age' > '25'
Eu então descobri que realmente posso resolver o problema usando ->
e convertido para int
:
select data->'name' as name from persons where cast(data->'age' as int) > 25
Isso funciona, mas não é tão bom que eu precise saber o tipo real (o tipo de age
documento JSON é number
assim mesmo, então por que o PostgreSQL não pode descobrir isso sozinho?).
Eu então descobri que, se eu converter manualmente para o text
uso da ::
sintaxe, tudo funcionará conforme o esperado também - embora agora possamos comparar as strings novamente.
select data->'name' as name from persons where data->'age'::text > '25'
Se eu tentar isso com o nome em vez da idade, não funcionará:
select data->'name' as name from persons where data->'name'::text > 'Jenny'
Isso resulta em um erro:
sintaxe de entrada inválida para o tipo json
Obviamente, não tenho nada aqui. Infelizmente, é muito difícil encontrar exemplos reais do uso de JSON com o PostgreSQL.
Alguma dica?
'Jenny'
com '"Jenny"'
.
data->'name'::text
, você está convertendo a'name'
string em texto, não no resultado. Você não recebe um erro ao comparar'25'
porque25
é um literal JSON válido; masJenny
não é (embora"Jenny"
seria).