У меня есть таблица, persons
которая содержит два столбца, id
и столбец на основе JSONB data
(эта таблица была только что сделана в демонстрационных целях, чтобы поиграться с поддержкой JSON в PostgreSQL).
Теперь предполагается, что он содержит две записи:
1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }
Предположим, я хочу получить имя каждого человека старше 25 лет. Я попробовал:
select data->'name' as name from persons where data->'age' > 25
К сожалению, это приводит к ошибке. Я могу решить эту проблему, используя ->>
вместо этого ->
, но тогда сравнения не будут работать так, как ожидалось, поскольку сравниваются не числа, а их представления в виде строк:
select data->'name' as name from persons where data->>'age' > '25'
Затем я понял, что на самом деле могу решить проблему, используя ->
и приведение к int
:
select data->'name' as name from persons where cast(data->'age' as int) > 25
Это работает, но не очень приятно, что мне нужно знать фактический тип (тип age
документа JSON в number
любом случае таков, так почему же PostgreSQL не может выяснить это сам по себе?).
Затем я понял, что, если я вручную преобразую text
в ::
синтаксис, все тоже будет работать, как и ожидалось - хотя мы сейчас снова сравниваем строки.
select data->'name' as name from persons where data->'age'::text > '25'
Если я тогда попробую это с именем вместо возраста, это не сработает:
select data->'name' as name from persons where data->'name'::text > 'Jenny'
Это приводит к ошибке:
неверный синтаксис ввода для типа json
Совершенно очевидно, что я ничего не понимаю здесь. К сожалению, довольно сложно найти какие-либо реальные примеры использования JSON с PostgreSQL.
Есть намеки?
'Jenny'
с '"Jenny"'
.
data->'name'::text
, вы'name'
приводите строку к тексту, а не результат. Вы не получите ошибку при сравнении с,'25'
потому что25
это допустимый литерал JSON; ноJenny
это не так (хотя"Jenny"
было бы).