Oracle SQL:如何删除 listagg 中的重复项
Posted
技术标签:
【中文标题】Oracle SQL:如何删除 listagg 中的重复项【英文标题】:Oracle SQL: How to remove duplicate in listagg 【发布时间】:2021-11-08 11:23:15 【问题描述】:使用 listagg 合并我的数据后,我想删除许多重复项。
Original Table
我的数据中总共只有 3 种技术,没有特定的模式。我想知道是否可以删除所有重复项并在相应行中仅保留 1 种类型?
select
NAME,
RTRIM(
REGEXP_REPLACE(
(LISTAGG(
NVL2(Membrane_column, 'Membrane, ', NULL)
|| NVL2(SNR_column, 'SNR, ', NULL)
|| NVL2(SMR_column, 'SMR, ', NULL)
) within group (ORDER BY name)),
'Membrane, |SNR, |SMR, ', '', '1', '1', 'c')
', ')
as TECHNOLOGY
from
Table A
我现在拥有的当前表
Name | Technology |
---|---|
A | SNR, SMR, SMR, SNR |
B | Membrane, SNR, SMR, Membrane |
C | SMR, SMR, Membrane |
想要的表
Name | Technology |
---|---|
A | SNR, SMR |
B | Membrane, SNR, SMR |
C | SMR, Membrane |
【问题讨论】:
想要的输出是什么? 完成。很抱歉不清楚前哨。 请将您的源数据发布为文本,而不是图像。 Why not upload images of code/errors when asking a question? idk 为什么我在发布表格时总是出错。这就是我发布图片的原因 请将其发布为纯文本或任何可以复制的内容,有人会编辑它。图片一点用都没有(手动输入所有数据真的很无聊)。 【参考方案1】:这可能是一个简单的方法:
select name, listagg(technology, ', ') within group (order by 1) -- or whatever order you need
from
(
select distinct name, technology
from tableA
)
group by name
【讨论】:
谢谢。但不是我想要的。在原始帖子中添加了所需的输出!【参考方案2】:也许只需创建 SNR/SMR/Membrane 列的 SUM,按名称对它们进行分组,然后将数字替换为您希望在输出中看到的字符串。
查询(第一步...)
select name
, sum( snr_column ), sum( smr_column ), sum( membrane_column )
from original
group by name
;
-- output
NAME SUM(SNR_COLUMN) SUM(SMR_COLUMN) SUM(MEMBRANE_COLUMN)
2 1 1 2
3 null 2 1
1 2 2 null
用 RTRIM() 替换总和、连接、删除尾随逗号
select
name
, rtrim(
case when sum( snr_column ) >= 1 then 'SNR, ' end
|| case when sum( smr_column ) >= 1 then 'SMR, ' end
|| case when sum( membrane_column ) >= 1 then 'Membrane' end
, ' ,'
) as technology
from original
group by name
order by name
;
-- output
NAME TECHNOLOGY
1 SNR, SMR
2 SNR, SMR, Membrane
3 SMR, Membrane
按要求的顺序对 CASE 进行编码。 DBfiddle
【讨论】:
你拯救了我的一天!这行得通!哈哈。太感谢了。想知道 regexp_replace 几天来是如何工作的,而实际上有一个非常简单的解决方案! :)【参考方案3】:从 Oracle 19c 开始 listagg
支持 distinct
关键字。 within group
也成为可选的。
with a as (
select column_value as a
from table(sys.odcivarchar2list('A', 'B', 'A', 'B', 'C')) q
)
select listagg(distinct a, ',')
from a
LISTAGG(DISTINCTA,',')
----------------------
A,B,C
livesql 示例here.
【讨论】:
谢谢。但不是我想要的。在原始帖子中添加了所需的输出! 如果您使用的是 Oracle 19c,这个答案就是您要找的。但这是关键,它只适用于 19c 起以上是关于Oracle SQL:如何删除 listagg 中的重复项的主要内容,如果未能解决你的问题,请参考以下文章
sql 从字符串..with毫秒的Oracle日期时间戳格式化。该示例还使用listagg在oracle中具有行的聚合
Oracle Database 19c 中的 LISTAGG DISTINCT
SQL 中的 STUFF 等效函数(MySQL 中的 GROUP_CONCAT / Oracle 中的 LISTAGG)