If I have a following query:
SELECT 'a' AS a, 1 AS b, CURRENT_DATE AS c;
It's possible to aggregate row to string as:
SELECT concat_ws(', ', a, b, c) FROM (
SELECT 'a' AS a, 1 AS b, CURRENT_DATE AS c
) AS T;
-- Result: "a, 1, <CURRENT DATE>"
But what I can't seem to find - if there is already existing function in postgres (version 9.3 or 9.4) that will produce the same result as above, but operating with a "*"
--
-- Something like:
--
-- some_function(<separator>, *) - ???
--
SELECT some_function(', ', *) FROM (
SELECT 'a' AS a, 1 AS b, CURRENT_DATE AS c
) AS T;
-- so the result would be - "a, 1, <CURRENT DATE>"
Thanks for any help.
答案 0 :(得分:1)
If you convert the row to a hstore
, you can do that:
select array_to_string(avals(hstore(x)), ', ')
from (
SELECT 'a' AS a, 1 AS b, CURRENT_DATE AS c
) x
hstore(x)
will convert all column values to strings and then put them into the hstore. avals
then extracts the values as a string array, and array_to_string
converts it into a comma separated list.
To do that for a regular table, you need to pass the table name, not *
select array_to_string(avals(hstore(foobar)), ', ')
from foobar;
If you don't want to (or can't) install the hstore
extension, you can do this with the JSON function although it requires one more level of nesting:
select string_agg(value, ', ')
from (
select (json_each_text(row_to_json(x1))).value
from (
SELECT 'a' AS a, 1 AS b, CURRENT_DATE AS c
) x1
) x2
Or to get the data from a table:
select string_agg(value, ', ')
from (
select (json_each_text(row_to_json(foobar))).value
from foobar
) x
If you want you can "hide" this in a function:
create or replace function concat_record(p_data anyelement, p_delim text)
returns text
as $$
select array_to_string(avals(hstore(p_data)), p_delim);
$$
language sql;
And then you can do:
select concat_record(foobar, ', ')
from foobar;
Unrelated but: you don't need the select
for the dummy data:
select *
from (
values ('a', 1, CURRENT_DATE)
) as x (a,b,c);
Is a bit shorter to write - especially if you have more than one row.
select *
from (
values
('a', 1, CURRENT_DATE),
('x', 2, date '2015-07-01')
) as x (a,b,c);