Postgres: Як перетворити рядок json в текст?


93

Значення Json може складатися з рядкового значення. напр .:

postgres=# SELECT to_json('Some "text"'::TEXT);
     to_json
-----------------
 "Some \"text\""

Як я можу витягти цей рядок як текстове значення postgres?

::TEXTне працює. Він повертає цитований json, а не вихідний рядок:

postgres=# SELECT to_json('Some "text"'::TEXT)::TEXT;
     to_json
-----------------
 "Some \"text\""

Дякую.

PS Я використовую PostgreSQL 9.3


stackoverflow.com/q/19414361/562459 може допомогти. Не може.
Mike Sherrill 'Cat Recall'

Подібна проблема з масивом рядків, stackoverflow.com/q/45243186/287948
Пітер Краус

Відповіді:


58

У PostgreSQL немає способу деконструювати скалярний об'єкт JSON. Таким чином, як ви зазначаєте,

select  length(to_json('Some "text"'::TEXT) ::TEXT);

становить 15,

Фокус у тому, щоб перетворити JSON у масив одного елемента JSON, а потім витягти цей елемент, використовуючи ->>.

select length( array_to_json(array[to_json('Some "text"'::TEXT)])->>0 );

повернеться 11.


8
Шкода, що json_extract_path_text()не може посилатися на кореневий елемент (AFAIK).
Ервін Брандштеттер

3
Цікаво, був мозковий штурм обговорення , мабуть , знову на стадії проектування API у 2012 році , в якому функція from_jsonотримала запропонованого, але не реалізований wiki.postgresql.org/wiki/JSON_API_Brainstorm
Nikola

146

У 9.4.4 використання #>>оператора працює для мене:

select to_json('test'::text) #>> '{}';

Для використання зі стовпцем таблиці:

select jsoncol #>> '{}' from mytable;

2
Здається, найпростішим рішенням у Postgres 9.4. Однак не працює для 9.3.
e79ene

2
@hasen ОП стверджує, що він намагається витягти текст із значення JSON, і to_json(...)це просто простий спосіб створити значення JSON, з яким можна працювати як приклад у короткому однорядковому операторі. Звичайно, ви б замінили його на ім'я стовпця JSON, якщо б ви запитували таблицю, як ви описуєте. Крім того, щоб усунути потенційну плутанину, ваш привід (...)::textє зайвим, оскільки #>>оператор повертає текст за визначенням (і це є причиною використання оператора в першу чергу). Ви можете зберегти дужки, але скинути акторський склад ::text.
Ян Тімоті

1
Хтось міг би пояснити, що #>>і що '{}'робить? Я не можу цілком стежити за цим, і жоден термін не є Google Friendly. Ця відповідь вирішила мою проблему, я просто хочу знати, чому.
valadil

1
@valadil Документація для #>>оператора тут .
Ian Timothy

1
@valadil У цьому випадку є об'єкт JSON верхнього рівня або кореневий text. Це може виглядати як рядок, але це об’єкт JSON. Щоб перетворити цей об'єкт з JSON в текст, використовуйте #>>оператор. Але цьому оператору потрібно, щоб ви вказали шлях. Шлях до цього кореневого об'єкта є {}. Це SELECT '"test"'::jsonb #>> '{}'означає "отримати об’єкт у кореневому шляху та перетворити його в текст".
Ян Тімоті

3

Містеру Цікавому було цікаво і з цього приводу. На додаток до #>> '{}'оператора, в версії 9.6+ можна отримати значення рядка jsonb з ->>оператором:

select to_jsonb('Some "text"'::TEXT)->>0;
  ?column?
-------------
 Some "text"
(1 row)

Якщо значення має json, то рішення полягає в тому, щоб спочатку передати jsonb:

select to_json('Some "text"'::TEXT)::jsonb->>0;
  ?column?
-------------
 Some "text"
(1 row)

0

Простий спосіб зробити це:

SELECT  ('[' || to_json('Some "text"'::TEXT) || ']')::json ->> 0;

Просто перетворіть рядок json у список json


0

- >> працює для мене.

версія postgres:

<postgres.version>11.6</postgres.version>

Запит:

select object_details->'valuationDate' as asofJson, object_details->>'valuationDate' as asofText from MyJsonbTable;

Вихід:

  asofJson       asofText
"2020-06-26"    2020-06-26
"2020-06-25"    2020-06-25
"2020-06-25"    2020-06-25
"2020-06-25"    2020-06-25

Дякую за вказівку, я виправив версію вище
Surinder

Оригінальне питання полягає в тому, як отримати значення рядка JSON у вигляді тексту (без ключа об’єкта). Ця відповідь - це лише різниця між ->та ->>під час використання ключа. Дивіться цю відповідь або цю відповідь .
Ян Тімоті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.