我在MacOSX上使用Postgres 9.3。
我想知道如何返回多个值(取决于某些条件)并使用它们以类似方式填充列表/数组中的列?
--DUMMY DATA
CREATE TABLE tbl (
id VARCHAR(2) PRIMARY KEY
,name TEXT
,year_born NUMERIC
,nationality TEXT
);
INSERT INTO tbl(id, name, year_born, nationality)
VALUES ('A1','Bill',2001,'American')
,('B1','Anna',1997,'Swedish')
,('A2','Bill',1991,'American')
,('B2','Anna',2004,'Swedish')
,('B3','Anna',1989,'Swedish')
,('A3','Bill',1995,'American');
SELECT * FROM tbl;
id | name | year_born | nationality
---+------+-----------+------------
A1 | Bill | 2001 | American
B1 | Anna | 1997 | Swedish
A2 | Bill | 1991 | American
B2 | Anna | 2004 | Swedish
B3 | Anna | 1989 | Swedish
A3 | Bill | 1995 | American
我使用name, nationality
子句汇总到列SELECT DISTINCT ON
,如下面的代码
CREATE TABLE another_tbl ( name TEXT, nationality TEXT, ids VARCHAR );
CREATE FUNCTION f1() RETURNS SETOF another_tbl AS
$$ SELECT DISTINCT ON (name, nationality) name, nationality, id
FROM tbl
GROUP BY name, nationality, ID;
$$ LANGUAGE sql
SELECT * FROM f1();
name | nationality | ids
------+-------------+-----
Anna | Swedish | B1
Bill | American | A1
所以,这是我不知道如何实现的东西,但我认为这相当容易。我希望列ids
由与name
列中的名称对应的所有ID填充,如下所示。
期望的输出:
SELECT * FROM f1();
name | nationality | ids
------+-------------+-----
Anna | Swedish | B1, B2, B3
Bill | American | A1, A2, A3
更新
在ARRAY
中找到VARCHAR
与ids
课一起用于another_tbl
列的Final statement returns character varying instead of
。但是,我收到了一个不匹配的来电,说at column 3
字符变化[] {{1}}。
答案 0 :(得分:3)
如果您希望将文本列作为结果,请使用GROUP BY
和汇总函数string_agg()
或array_agg()
构建一个数组
但是放弃现在多余的DISTINCT ON
。
SELECT name, nationality, string_agg(id, ',') AS ids
FROM tbl
GROUP BY 1, 2
ORDER BY 1, 2;
函数定义的RETURNS
子句必须匹配,如@ozczecho建议:
CREATE FUNCTION f1()
RETURNS TABLE(name text, nationality text, ids text) AS
-- varchar[] for array_agg()
$func$
SELECT t.name, t.nationality, string_agg(t.id, ',') AS ids
FROM tbl t
GROUP BY 1, 2
ORDER BY 1, 2;
$func$ LANGUAGE sql;
答案 1 :(得分:1)
我相信你应该改变:
RETURNS SETOF another_tbl
为:
RETURNS TABLE(name TEXT, nationality TEXT, ids VARCHAR[])
答案 2 :(得分:0)
好的,它可以使用array_agg
函数。
CREATE FUNCTION f1() RETURNS SETOF another_tbl AS
$$ SELECT DISTINCT ON (name, nationality) name, nationality, array_agg(id)
FROM tbl
GROUP BY name, nationality
$$ LANGUAGE sql
SELECT * FROM f();
name | nationality | ids
-----+-------------+-----------
Anna | Swedish | {B1,B2,B3}
Bill | American | {A1,A2,A3}
将函数array_to_string
添加到array_agg(id)
后,我们得到了所需的输出
name | nationality | ids
-----+-------------+---------
Anna | Swedish | B1,B2,B3
Bill | American | A1,A2,A3