SELECT json_array_elements('["one", "two"]'::json)
gives result
| json_array_elements | | :------------------ | | "one" | | "two" |
I would like to have the same but without the quotes:
one
two
Looks like I can't use ->>
here because I don't have field names in the JSON. It's just an array of strings.
Postgres version: PostgreSQL 10.0 on x86_64-apple-darwin, compiled by i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 23361100), 64-bit
-
What version of PostgreSQL?Vérace– Vérace2018年05月27日 18:37:14 +00:00Commented May 27, 2018 at 18:37
-
1This question have an answer here: dba.stackexchange.com/a/57121/110455McNets– McNets2018年05月27日 18:37:29 +00:00Commented May 27, 2018 at 18:37
-
@McNets - what about this?Vérace– Vérace2018年05月27日 18:42:36 +00:00Commented May 27, 2018 at 18:42
-
@Vérace on db-fiddle shows results without quotes but dbfiddle.uk shows results with quotes. I can't check it on my postgres VM (I don't remember the password) but I suppose it will show the quotes.McNets– McNets2018年05月27日 19:32:09 +00:00Commented May 27, 2018 at 19:32
-
2@Vérace psql shows it with quotes tooMcNets– McNets2018年05月27日 19:37:35 +00:00Commented May 27, 2018 at 19:37
4 Answers 4
The default json->text
coercion outputs with a double quote ("
) because coercing from text
to a json
string requires you to double-quote your input. To get rid of the double-quotes, use TRIM
SELECT x, trim('"' FROM x::text)
FROM json_array_elements('["one", "two"]'::json) AS t(x);
x | btrim
-------+-------
"one" | one
"two" | two
(2 rows)
Important point though, you lose some utility if you do that. All JSONB types get returned in a textual form that can be used to go back to jsonb
with the text->jsonb
coercion. It's a bijective mapping function. Losing that means null
and "null"
are the same, as are 1
and "1"
.
SELECT x, trim('"' FROM x::text)
FROM json_array_elements('[null, "null", 1, "1"]') AS t(x);
x | btrim
--------+-------
null | null
"null" | null
1 | 1
"1" | 1
(4 rows)
Internals..
If you want to know what's happening. All types can provide an _out
which takes them to text
or _send
which takes them to binary representation and a reciprocal _in
and _recv
which takes them from those forms and maps back to the types. Here you're getting jsonb_out
,
jsonb_out
which callsJsonbToCstring
JsonbToCstring
which callsJsonbToCStringWorker
JsonbToCStringWorker
which callsjsonb_put_escaped_value
jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
which callsescape_json
escape_json(StringInfo buf, const char *str)
which adds the"
and it's hardcoded. No other way.
-
Note that btrim gives incorrect result if the string contains double quotes while @slava-v's answer below is better:
SELECT x, trim('"' FROM x::text), x#>>'{}' FROM json_array_elements('[null, "nu\"ll", 1, "1"]') AS t(x);
psmith– psmith2022年06月07日 03:40:28 +00:00Commented Jun 7, 2022 at 3:40
SELECT value#>>'{}' as col FROM json_array_elements('["one", "two"]'::json);
Result:
col
---
one
two
-
5As a bit of an explanation: The operators that contain
>>
seem to generally convert a JSON to unescaped text: postgresql.org/docs/current/functions-json.html. This answer is probably preferable since the escaping is probably not limited to adding quotation marks, but also escapes quotation marks in the text and some special characters. The samples above just so happen not to contain any. ("Probably" because I didn’t test it.)Dawn Drescher– Dawn Drescher2019年07月04日 15:12:00 +00:00Commented Jul 4, 2019 at 15:12 -
4Rather the
#>>
is a JSON operator to return an object at a path, see: postgresql.org/docs/10/functions-json.htmljso– jso2019年08月29日 12:02:23 +00:00Commented Aug 29, 2019 at 12:02 -
8"How do you unquote a JSON string in postgres?" "Oh it's easy, just add
#>>'{}'
after. Should be obvious." 😂 Take your upvote, wizard!Sarke– Sarke2020年09月16日 10:10:11 +00:00Commented Sep 16, 2020 at 10:10
SELECT json_array_elements_text('["one", "two"]'::json)
of if using jsonb instead:
SELECT jsonb_array_elements_text('["one", "two"]'::jsonb)
You could use jsonb_array_elements
instead:
SELECT jsonb_array_elements('["one", "two"]'::jsonb) ->> 0
Result:
col
---
one
two
Explore related questions
See similar questions with these tags.