Sql 如何从多个LISTAGG';Oracle中的非结构化列
在下面的脚本中,我缺少什么逻辑来消除Listag函数中的重复值 下面是sys.privs表:Sql 如何从多个LISTAGG';Oracle中的非结构化列,sql,oracle11g,oracle-sqldeveloper,Sql,Oracle11g,Oracle Sqldeveloper,在下面的脚本中,我缺少什么逻辑来消除Listag函数中的重复值 下面是sys.privs表: SQL> desc sys.privs Name Null? Type ----------------------------------------- -------- ---------------------------- GRANTEE
SQL> desc sys.privs
Name Null? Type
----------------------------------------- -------- ----------------------------
GRANTEE VARCHAR2(30 CHAR)
GRANTED_ROLE NOT NULL VARCHAR2(30)
PRIVILEGE NOT NULL VARCHAR2(40)
OWNER NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL VARCHAR2(30)
下面是脚本
SELECT grantee,
LISTAGG(granted_role, '-') WITHIN GROUP (ORDER BY granted_role) AS granted_role,
LISTAGG(privilege, '-') WITHIN GROUP (ORDER BY privilege) AS privs,
owner,
table_name
FROM (
SELECT UNIQUE
grantee,
granted_role,
privilege,
owner,
table_name
FROM sys.privs
)
GROUP BY grantee, owner, table_name;
您可以利用
listag()
忽略NULL
值这一事实来实现这一点。因此,使用row_number()
枚举重复项,然后只拉入第一个值:
SELECT grantee,
LISTAGG(CASE WHEN seqnum_granted_role = 1 THEN granted_role END, '-')
WITHIN GROUP (ORDER BY granted_role) AS granted_role,
LISTAGG(CASE WHEN seqnum_privilege = 1 THEN privilege END, '-')
WITHIN GROUP (ORDER BY privilege) AS privs,
owner,
table_name
FROM (SELECT grantee, granted_role, privilege,
owner, table_name,
ROW_NUMBER() OVER (PARTITION BY grantee, owner, table_name, granted_role
ORDER BY grantee
) as seqnum_granted_role,
ROW_NUMBER() OVER (PARTITION BY grantee, owner, table_name, privilege
ORDER BY grantee
) as seqnum_privilege
FROM sys.privs
) p
GROUP BY grantee, owner, table_name;