我正在尝试运行此查询
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和角色名称。如果我做错了一切,您能指出我正确的方向吗?
答案 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
的一部分,因此您也可以使用where
或having
。
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
)