CodeRang
Темы SQL

JSON SQL: работа с JSON и JSONB в PostgreSQL

JSON SQL нужен, когда часть данных хранится внутри JSON-объектов и массивов. На примере PostgreSQL разберём извлечение вложенных полей, отличие -> от ->> и приведение JSON-значений к SQL-типам.

Обновлено · Команда SQL Arena

Что потренируете

  • Извлекать JSON-объекты через -> и текстовые значения через ->>
  • Работать с вложенными полями jsonb
  • Приводить значения из JSON к числам и другим SQL-типам
  • Разворачивать массивы через jsonb_array_elements
  • Отличать отсутствующий ключ от JSON null

Пример задачи в тренажёре

Так выглядит задача в SQL Arena: условие, редактор, результат и схема базы.

Пред.След.Случайная
ЗаданиеОтправкиAI Mentor
Найдите заказы дороже 100 и достаньте город из JSON

В таблице orders часть данных заказа хранится в колонке payload типа jsonb. Выведите только заказы с суммой не меньше 100. В результате нужны order_id, city и total. Город лежит внутри объекта delivery, а сумма записана в JSON как строка. Отсортируйте строки по id заказа.

Запрос 1PostgreSQLv16
SELECT
  o.id AS order_id,
  o.payload->'delivery'->>'city' AS city,
  (o.payload->>'total')::numeric AS total
FROM orders o
WHERE (o.payload->>'total')::numeric >= 100
ORDER BY o.id;
Отправить
Результатcustomersorders
Ответ принят

Как работать с JSON и JSONB в SQL-запросе

Начинаем с вложенного поля города. Выражение o.payload->'delivery' возвращает JSON-объект delivery, а следующий оператор ->>'city' достаёт из него текст. Разница важна: -> сохраняет JSON-тип результата, а ->> возвращает текстовое значение. Поэтому для цепочки вложенных объектов удобно сначала идти через ->, а конечное скалярное значение получать через ->>.

Сумма заказа хранится как строка внутри JSON. Выражение o.payload->>'total' поэтому имеет текстовый тип, даже если визуально значение выглядит как число. Для числового сравнения используется приведение ::numeric. Без него PostgreSQL сравнивал бы текст, а это другая операция: строка '90' может оказаться больше строки '100' при лексикографическом сравнении. То же приведение сделано в SELECT, чтобы колонка total в результате была числом, а не текстом.

Условие WHERE оставляет только значения от 100 и выше. ORDER BY o.id фиксирует порядок результата, что особенно полезно при автоматической проверке. В более сложных JSON-задачах к этим приёмам добавляются jsonb_array_elements для массивов, проверки типа значения и отдельная обработка null. Это уже не синтаксический трюк, а обычная работа с полуструктурированными данными.

В PostgreSQL для хранения JSON используются типы json и jsonb. JSONB хранит данные в бинарном представлении и поддерживает дополнительные операторы и индексацию. Оператор -> возвращает JSON-значение, а ->> извлекает его как текст. Поэтому числовое значение после ->> обычно нужно явно привести, например к numeric или integer. Для вложенных объектов операторы можно объединять в цепочки: сначала перейти к нужному объекту через ->, затем получить конечное скалярное значение через ->>.

SQLPostgreSQL v16
SELECT
  o.id AS order_id,
  o.payload->'delivery'->>'city' AS city,
  (o.payload->>'total')::numeric AS total
FROM orders o
WHERE (o.payload->>'total')::numeric >= 100
ORDER BY o.id;
Результат запроса
order_idcitytotal
102Boston145.00
104Rome210.00
105Amsterdam119.90

Ошибки при работе с JSONB PostgreSQL

01

Путать -> и ->>

Оператор -> возвращает JSON, а ->> — текст. Если попытаться привести к numeric целый JSON-объект или сравнить его с обычной строкой, запрос либо упадёт, либо потребует лишних преобразований. Обычно промежуточные узлы читают через ->, а конечное значение — через ->>.

02

Сравнивать число из JSON как текст

JSON часто приходит из API, где часть чисел записана строками. Условие payload->>'total' >= '100' сравнивает строки, а не числовые значения. Для суммы, количества или рейтинга сначала приведите результат к integer, numeric или другому подходящему типу.

03

Считать отсутствующий ключ и JSON null одним случаем

У объекта может вообще не быть ключа coupon, а может быть ключ со значением null. Для аналитики и проверок качества данных это разные ситуации. Простого извлечения поля иногда недостаточно: нужно отдельно проверить наличие ключа и его JSON-значение.

Задачи по теме в тренажёре

Курс «JSON и вложенные данные»

После базового извлечения полей полезно перейти к задачам, где структура начинает мешать простому SELECT. Например, найти город внутри JSON, проверить, когда error действительно равен null, разобрать значения импорта или определить, что items оказался не массивом. На следующем уровне появляются расчёты по массивам и вложенным объектам: количество позиций заказа, выручка по городам, средняя цена товара по категориям. Для системного прохождения этих тем в SQL Arena есть курс «JSON и вложенные данные»: теория идёт вместе с задачей в каждом уроке, а первые главы доступны бесплатно.

Частые вопросы

Что такое JSON SQL?

JSON SQL обычно называют работу с JSON-данными внутри SQL-запросов. Возможности зависят от СУБД: например, PostgreSQL поддерживает типы json и jsonb, операторы извлечения значений и функции для обработки JSON.

Что такое JSONB в PostgreSQL?

JSONB — бинарный тип PostgreSQL для хранения JSON-документов. Он позволяет обращаться к вложенным значениям, проверять содержимое и использовать специальные индексы для некоторых операций.

Чем JSON отличается от JSONB в PostgreSQL?

Тип json сохраняет исходное текстовое представление документа, а jsonb хранит разобранную бинарную структуру. JSONB обычно удобнее для поиска и обработки данных и поддерживает дополнительные возможности индексации.

Как получить значение из JSONB в PostgreSQL?

Оператор -> возвращает поле как JSON, а ->> возвращает его текстовое значение. Для вложенных объектов операторы можно объединять, например payload->'delivery'->>'city'.

Как сравнивать числа из JSON в SQL?

Если значение извлечено оператором ->>, PostgreSQL получает текст. Перед числовым сравнением его нужно привести к подходящему типу, например (payload->>'total')::numeric.

Практика JSON SQL на задачах

В SQL Arena есть 1 192 задачи с автопроверкой. У каждой задачи свои таблицы, поэтому нельзя заучить один шаблон под все примеры. Бесплатно доступны 292 задачи без карты, в том числе задания по JSON. Ответ проверяется и на скрытых данных. Если хочется идти последовательно от операторов -> и ->> к массивам и вложенным структурам, продолжайте в курсе «JSON и вложенные данные».

Решать задачи по JSON