Postgres string_agg函数未识别为聚合函数

时间:2019-03-19 16:02:39

标签: postgresql

我正在尝试运行此查询

SELECT  u.*, string_agg(CAST(uar.roleid AS VARCHAR(100)), ',') AS roleids, string_agg(CAST(r.role AS VARCHAR(100)), ',') AS systemroles
FROM idpro.users AS u 
INNER JOIN  idpro.userapplicationroles AS uar ON u.id = uar.userid 
INNER JOIN  idpro.roles AS r ON r.id = uar.roleid 
GROUP BY u.id, uar.applicationid
HAVING u.organizationid = '77777777-f892-4f4a-8328-c31df32bd6ba'
    AND uar.applicationid = 'd88fbf05-c048-4697-8bf3-036f39897183'
    AND (u.statusid = '7f9f0b75-44b7-4216-bf2a-03abc47dcff8') 
    AND uar.roleid IN ('cc9ada1c-fa21-400b-be98-c563ebb65a9c','de087148-4788-43da-89e2-dd7dff097735');

但是,我得到一个错误提示

ERROR:  column "uar.roleid" must appear in the GROUP BY clause or be used in an aggregate function
LINE 9:  AND uar.roleid IN ('cc9ada1c-fa21-400b-be98-c563ebb65a9c','...

string_agg()是一个聚合函数,不是吗?我的意图(如果不是很明显)是返回每个用户记录,并在逗号分隔的列表中包含角色ID和角色名称。如果我做错了一切,您能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:3)

您正在过滤数据,因此将需要一个WHERE子句。这个tutorial值得一读。

SELECT  u.*, 
        string_agg(CAST(uar.roleid AS VARCHAR(100)), ',') AS roleids,
        string_agg(CAST(r.role AS VARCHAR(100)), ',') AS systemroles
FROM idpro.users AS u 
INNER JOIN  idpro.userapplicationroles AS uar ON u.id = uar.userid 
INNER JOIN  idpro.roles AS r ON r.id = uar.roleid 
WHERE u.organizationid = '77777777-f892-4f4a-8328-c31df32bd6ba'
    AND uar.applicationid = 'd88fbf05-c048-4697-8bf3-036f39897183'
    AND (u.statusid = '7f9f0b75-44b7-4216-bf2a-03abc47dcff8') 
    AND uar.roleid IN ('cc9ada1c-fa21-400b-be98-c563ebb65a9c','de087148-4788-43da-89e2-dd7dff097735');
GROUP BY u.id, uar.applicationid

HAVING子句有助于过滤汇总值或组。

由于您要按u.id进行分组,因此您拥有u表中的access to every column的表主键。您可以使用where子句或having子句。

对于uar.applicationid,它是group by的一部分,因此您也可以使用wherehaving

uar.roleid不是group by子句的一部分,因此要在having子句中使用,必须考虑合计值。

以下示例过滤出汇总长度超过10个字符的行。

HAVING length(string_agg(CAST(uar.roleid AS VARCHAR(100)), ',')) > 10

在数字字段上,更常见的用法是过滤汇总行数是否小于阈值(having count(*) > 2)或某种类型的总和(having sum(vacation_days) > 21