当每个列都包含NULL
值时,我需要用逗号分隔多个列中包含的值:
with
data as (
select null a, null b, null c from dual
union all
select 'a' a, null b, null c from dual
union all
select null a, 'b' b, null c from dual
union all
select null a, null b, 'c' c from dual
union all
select 'a' a, 'b' b, null c from dual
union all
select 'a' a, null b, 'c' c from dual
union all
select null a, 'b' b, 'c' c from dual
union all
select 'a' a, 'b' b, 'c' c from dual
)
select a,b,c
,case
when a is not null and b is not null and c is not null then a || ',' || b || ',' ||c
when a is not null and b is not null then a || ',' || b
when a is not null and c is not null then a || ',' || c
when b is not null and c is not null then b || ',' || c
when a is not null then a
when b is not null then b
when c is not null then c
end abc
from data
结果:
A B C ABC
a a
b b
c c
a b a,b
a c a,c
b c b,c
a b c a,b,c
是否有一种方法比我abc
所做的更简单,最好不必使用PL / SQL?
答案 0 :(得分:3)
您真正想要的功能是concat_ws()
,但Oracle没有。但是这里有一个比你的方法更麻烦的替代方案:
select a, b, c,
trim(both ',' from replace(replace(a || ',' || b || ',' || c, ',,', ','), ',,', ',')
from data;
这将使用逗号创建字符串。 Oracle忽略字符串连接中的NULL
值。然后删除重复的逗号以及前导和尾随逗号。
另一种方法是:
select a, b, c,
trim(trailing ',' from
coalesce(a || ',', '') || coalesce(b || ',', '') || coalesce(c || ',', '')
)
from data;
我其实更喜欢这个版本。它更具普遍性;中间结果没有一串逗号粘在字符串的中间。
答案 1 :(得分:1)
通过将,
连接到列值(a和b)(如果它们非空并且修剪尾随,
)来实现此目的。
select a, b, c,
trim(trailing ',' from
case when a is null then '' else a||',' end ||
case when b is null then '' else b||',' end ||
case when c is null then '' else c end) abc
from data
答案 2 :(得分:0)
基于不同版本的TRIM的解决方案应该有效,因为逗号不应该是合法的"数据中的字符。如果是,则应使用其他分隔符。但是,如果您的数据中有逗号,则TRIM解决方案可能会在结果的开头或结尾删除逗号,即使它们是数据的一部分。
您可以使用SUBSTR而不是TRIM来避免这种情况。像
这样的东西select a, b, c,
substr(case when a is not null then ',' || a end ||
case when b is not null then ',' || b end ||
case when c is not null then ',' || c end
, 2) as abc
from data
;
非常类似于vkp的解决方案,逗号从后面移到前面,这样SUBSTR可以非常简单地编写。对于任何非null值,先添加逗号,然后连接结果。然后SUBSTR读取除第一个字符以外的所有内容(它从字符编号2开始读取),或者如果整个连接为NULL则返回NULL - 完全符合需要。
答案 3 :(得分:0)
这有效:
SELECT a,b,c
,trim(trailing ',' from nvl2(a,a || ',', '') || nvl2(b,b || ',', '') || nvl2(c,c || ',', ''))` abc
FROM data;
**编辑**
这适用于多字符(逗号空格)分隔符:
SELECT a,b,c
,rtrim( nvl2(a,a || ', ', '') || nvl2(b,b || ', ', '') || nvl2(c,c || ', ', ''), ', ' ) abc
FROM data;