我有桌子" foo"如下:
user_id attr_name attr_value
-------------------------------
joe user_id abc123
joe permission A
joe permission B
joe permission C
我想要以下结果:
user_id permission_List
-----------------------------
abc123 A, B, C
我可以通过以下非常简单的查询获得所需的结果:
select
user_id,
LISTAGG(permissions,', ') within group(order by permissions) AS permission_list
from
(
SELECT a1.attr_value AS user_id,
a2.attr_value AS permissions
from foo a1
JOIN foo a2 on a1.user_id=a2.user_id
WHERE a1.attr_name='user_id'
and a2.attr_name='permission'
and a1.user_id='joe'
)
group by user_id;
必须有一个更清洁的方式!有什么建议吗?
答案 0 :(得分:2)
唉,PIVOT运算符不能与LISTAGG一起使用,所以你仍然需要使用旧的旋转方式(条件聚合)。但您可以简化查询,如下所示。
注意:在示例数据中,您有第一列名为USER_ID,值为“john” - 但是您有一个名为USER_ID的属性,其值为“abc123”。这是没有意义的。我在输出中使用了NEW_USER_ID的列名,但我希望在现实生活中你不必忍受这样的废话。
您在下面看到的WITH子句不是解决方案的一部分;我把它包括在内只用于测试。删除它,在剩下的查询中使用您的实际表和列名称。
with
inputs ( user_id, attr_name, attr_value ) as (
select 'joe', 'user_id' , 'abc123' from dual union all
select 'joe', 'permission', 'A' from dual union all
select 'joe', 'permission', 'B' from dual union all
select 'joe', 'permission', 'C' from dual
)
select user_id,
min(case attr_name when 'user_id' then attr_value end) as new_user_id,
listagg(case attr_name when 'permission' then attr_value end, ', ')
within group (order by attr_value) as permission_list
from inputs
where attr_name in ('user_id', 'permission')
and user_id = 'joe' -- if needed
group by user_id
;
USER_ID NEW_USER_ID PERMISSION_LIST
------------ ------------ ------------------
joe abc123 A, B, C