J'ai une table, persons
qui contient deux colonnes, une id
et une data
colonne basée sur JSONB (cette table vient d'être créée à des fins de démonstration pour jouer avec le support JSON de PostgreSQL).
Maintenant, supposons qu'il contienne deux enregistrements:
1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }
Maintenant, je suppose que je veux obtenir le nom de toute personne âgée de plus de 25 ans. Ce que j'ai essayé, c'est:
select data->'name' as name from persons where data->'age' > 25
Malheureusement, cela entraîne une erreur. Je peux le résoudre en utilisant ->>
au lieu de ->
, mais les comparaisons ne fonctionnent plus comme prévu, car non les chiffres sont comparés, mais leurs représentations sous forme de chaînes:
select data->'name' as name from persons where data->>'age' > '25'
J'ai ensuite compris que je pouvais réellement résoudre le problème en utilisant ->
et un cast pour int
:
select data->'name' as name from persons where cast(data->'age' as int) > 25
Cela fonctionne, mais ce n'est pas si agréable que je dois connaître le type réel (le type de age
dans le document JSON estnumber
toute façon, alors pourquoi PostgreSQL ne peut-il pas le comprendre par lui-même?).
J'ai ensuite compris que si je convertis manuellement en text
utilisant la ::
syntaxe, tout fonctionne aussi comme prévu - bien que nous comparions à nouveau les chaînes.
select data->'name' as name from persons where data->'age'::text > '25'
Si j'essaye ensuite avec le nom au lieu de l'âge, cela ne fonctionne pas:
select data->'name' as name from persons where data->'name'::text > 'Jenny'
Il en résulte une erreur:
syntaxe d'entrée non valide pour le type json
De toute évidence, je ne reçois pas quelque chose ici. Malheureusement, il est assez difficile de trouver des exemples concrets d'utilisation de JSON avec PostgreSQL.
Des indices?
'Jenny'
avec '"Jenny"'
.
data->'name'::text
, vous transformez la'name'
chaîne en texte, pas le résultat. Vous n'obtenez pas d'erreur lors de la comparaison avec'25'
car25
est un littéral JSON valide; maisJenny
n'est pas (bien que ce"Jenny"
serait).