抑制 Oracle 中的重复值 sql
Suppress Repeating values in Oracle sql
我正在使用 Oracle BIPublisher 构建 sql 查询。现在我的查询输出是:
ControlID Role
1 ABC
1 SJD
1 DKF
2 LLL
2 IJK
如何编写 sql 以便输出像这样?
ControlID Role
1 ABC
SJD
DKF
2 LLL
IJK
*** 编辑:
我能够使用 Tim 的解决方案进行抑制:
SELECT DISTINCT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY GRCC_CONTROL_ID ORDER BY erp_user_name) = 1
THEN GRCC_CONTROL_ID ELSE NULL END AS GRCC_CONTROL_ID ,
,role
from GRC_CTRL_AAC_INCIDENTS
ORDER BY GRCC_CONTROL_ID, role
我想将 control_id 替换为实际的控件名称,但它位于单独的 table 中。当我在上面的查询中替换 c.name 时,我收到一条错误消息
'FROM' keyword not found where expected
:
SELECT DISTINCT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY c.name ORDER BY role) = 1
THEN c.name ELSE NULL END AS c.name ,
role
from GRC_CTRL_AAC_INCIDENTS
,GRC_CTRL_CCM_CONTROL_TL c
where GRCC_CONTROL_ID = c.id
ORDER BY c.name, role
这确实是一个表示要求,因此最好在您的表示层中处理(例如 PHP 或 Java)。也就是说,我们可以使用 ROW_NUMBER
:
来处理这个问题
SELECT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY ControlID ORDER BY Role) = 1
THEN ControlID ELSE NULL END AS ControlID,
t.Role
FROM yourTable t
ORDER BY
t.ControlID,
t.Role;
编辑:
您使用的是旧式 ANSI-92 之前的连接语法是您实际更新的查询尝试。不要那样做。相反,使用带有别名的显式连接:
SELECT DISTINCT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY c.name ORDER BY role) = 1
THEN c.name ELSE NULL END AS name, -- NOT c.name
role
FROM GRC_CTRL_AAC_INCIDENTS t
INNER JOIN GRC_CTRL_CCM_CONTROL_TL c
ON t.GRCC_CONTROL_ID = c.id
ORDER BY
c.name,
role;
我将尝试回答您的最终目标。
使用您所采用的方法,如果不在 XML 中公开 controlID,将很难正确显示数据。如果 ControlID 未出现在 XML 中,您将无法将角色与报表中同一 ControlID 中的其他角色分组在一起。角色 SJD 与 LLL 具有相同的 ControlID。
现在是使用 BI Publisher 中的 "regrouping" 或 "for-each-group" 功能的好时机。
<?for-each-group: BASE-GROUP;GROUPING-ELEMENT?>
假设这两个元素在一个 ROW
元素中:
<?for-each-group: ROW;ControlID?>
<?sort:ControlID?>
<?ControlID?>
<?for-each:current-group()?>
<?sort:Role?>
<?Role?>
<?end for-each?>
<?end for-each-group?>
您可以轻松地将其添加到重复的 table 行中,并为内部 for-each 使用嵌套的 table。
Internet 上有很多关于 BI Publisher 重组功能的附加文档和示例。
我正在使用 Oracle BIPublisher 构建 sql 查询。现在我的查询输出是:
ControlID Role
1 ABC
1 SJD
1 DKF
2 LLL
2 IJK
如何编写 sql 以便输出像这样?
ControlID Role
1 ABC
SJD
DKF
2 LLL
IJK
*** 编辑: 我能够使用 Tim 的解决方案进行抑制:
SELECT DISTINCT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY GRCC_CONTROL_ID ORDER BY erp_user_name) = 1
THEN GRCC_CONTROL_ID ELSE NULL END AS GRCC_CONTROL_ID ,
,role
from GRC_CTRL_AAC_INCIDENTS
ORDER BY GRCC_CONTROL_ID, role
我想将 control_id 替换为实际的控件名称,但它位于单独的 table 中。当我在上面的查询中替换 c.name 时,我收到一条错误消息
'FROM' keyword not found where expected
:
SELECT DISTINCT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY c.name ORDER BY role) = 1
THEN c.name ELSE NULL END AS c.name ,
role
from GRC_CTRL_AAC_INCIDENTS
,GRC_CTRL_CCM_CONTROL_TL c
where GRCC_CONTROL_ID = c.id
ORDER BY c.name, role
这确实是一个表示要求,因此最好在您的表示层中处理(例如 PHP 或 Java)。也就是说,我们可以使用 ROW_NUMBER
:
SELECT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY ControlID ORDER BY Role) = 1
THEN ControlID ELSE NULL END AS ControlID,
t.Role
FROM yourTable t
ORDER BY
t.ControlID,
t.Role;
编辑:
您使用的是旧式 ANSI-92 之前的连接语法是您实际更新的查询尝试。不要那样做。相反,使用带有别名的显式连接:
SELECT DISTINCT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY c.name ORDER BY role) = 1
THEN c.name ELSE NULL END AS name, -- NOT c.name
role
FROM GRC_CTRL_AAC_INCIDENTS t
INNER JOIN GRC_CTRL_CCM_CONTROL_TL c
ON t.GRCC_CONTROL_ID = c.id
ORDER BY
c.name,
role;
我将尝试回答您的最终目标。
使用您所采用的方法,如果不在 XML 中公开 controlID,将很难正确显示数据。如果 ControlID 未出现在 XML 中,您将无法将角色与报表中同一 ControlID 中的其他角色分组在一起。角色 SJD 与 LLL 具有相同的 ControlID。
现在是使用 BI Publisher 中的 "regrouping" 或 "for-each-group" 功能的好时机。
<?for-each-group: BASE-GROUP;GROUPING-ELEMENT?>
假设这两个元素在一个 ROW
元素中:
<?for-each-group: ROW;ControlID?>
<?sort:ControlID?>
<?ControlID?>
<?for-each:current-group()?>
<?sort:Role?>
<?Role?>
<?end for-each?>
<?end for-each-group?>
您可以轻松地将其添加到重复的 table 行中,并为内部 for-each 使用嵌套的 table。
Internet 上有很多关于 BI Publisher 重组功能的附加文档和示例。