У меня есть таблица, 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"было бы).