Tengo una tabla, persons
que contiene dos columnas, una id
y una data
columna basada en JSONB (esta tabla acaba de hacerse con fines demostrativos para jugar con el soporte JSON de PostgreSQL).
Ahora, se supone que contiene dos registros:
1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }
Ahora, supongo que quiero obtener el nombre de cada persona mayor de 25 años. Lo que he intentado es:
select data->'name' as name from persons where data->'age' > 25
Desafortunadamente, esto da como resultado un error. Puedo resolverlo usando en ->>
lugar de ->
, pero las comparaciones ya no funcionan como se esperaba, ya que no se comparan los números, sino sus representaciones como cadenas:
select data->'name' as name from persons where data->>'age' > '25'
Luego descubrí que realmente puedo resolver el problema usando ->
y un elenco para int
:
select data->'name' as name from persons where cast(data->'age' as int) > 25
Esto funciona, pero no es tan bueno que tenga que saber el tipo real (el tipo de age
en el documento JSON es de number
todos modos, entonces, ¿por qué PostgreSQL no puede resolver eso por sí mismo?).
Luego descubrí que si convierto manualmente el text
uso de la ::
sintaxis, todo funciona como se esperaba, aunque ahora estamos comparando cadenas nuevamente.
select data->'name' as name from persons where data->'age'::text > '25'
Si luego intento esto con el nombre en lugar de la edad, no funciona:
select data->'name' as name from persons where data->'name'::text > 'Jenny'
Esto da como resultado un error:
sintaxis de entrada no válida para el tipo json
Obviamente, no consigo algo aquí. Desafortunadamente, es bastante difícil encontrar ejemplos del mundo real del uso de JSON con PostgreSQL.
¿Alguna pista?
'Jenny'
con '"Jenny"'
.
data->'name'::text
, está convirtiendo la'name'
cadena a texto, no el resultado. No obtiene un error al comparar'25'
porque25
es un literal JSON válido; peroJenny
no lo es (aunque"Jenny"
lo sería).