我有一些表TABLE1
包含数据:
+------------+
| COL1 |
+------------+
| FOO |
| BAR |
| (null) |
| EXP |
+------------+
(FIDDLE)
执行时:
SELECT listagg(col1, '#') within group(ORDER BY rownum)
FROM table1
我收到:FOO#BAR#EXP
但我希望:FOO#BAR##EXP
(LISTAGG
忽略空单元格:/)
没有编写自己的函数就能实现这个目标吗?
答案 0 :(得分:4)
select replace(listagg(NVL(col1, '#'), '#')
within group(order by rownum),'###','##') from table1
你可以在这里使用NVL(col1, '#')
,你可以传递任何值而不是null。
答案 1 :(得分:2)
select substr(listagg('#'||col1) within group (order by rownum),2)
from table1
在每个值之前添加分隔符(这仅为NULL生成分隔符),然后在没有分隔符的情况下聚合,并剥离前导分隔符。
答案 2 :(得分:1)
另一种方法,使用model clause。
SQL> select rtrim(res, '#') as col1
2 from ( select res
3 , rn
4 from table1
5 model
6 dimension by (rownum as rn)
7 measures(cast(null as varchar2(500)) as res, col1)
8 rules(
9 res[any] order by rn desc= col1[cv()] || '#' || res[cv() + 1]
10 )
11 )
12 where rn = 1
13 /
COL1
--------------------
FOO#BAR##EXP
答案 3 :(得分:0)
试试这个
select
REPLACE(listagg(NVL(col1,' '), '#') within group(order by rownum),'# #','##')
from table1
答案 4 :(得分:0)
尝试这种方式:
select replace(
listagg(coalesce(col1,'replace'), '#')
within group(order by rownum),
'replace','')
from table1
Sql Fiddle Demo
答案 5 :(得分:0)
请尝试:
select replace(listagg(nvl(col1, '#') , '#')
within group(order by rownum), '##', '#')
from table1
答案 6 :(得分:0)
恕我直言,值得一提的是,使用 listagg
时,您可能会遇到结果值的 4000 个字符的限制,然后寻求一些替代解决方案。解决方案是xmlagg
,相比之下,它尊重 null
值。因此,请考虑将基于占位符的技巧与 listagg
结合使用是否值得。
(我的情况正好相反:我需要 ignore 完全符合 listagg
的空值,但后来我达到了限制并被迫学习使用 xmlagg
子句忽略值. 使用 nvl2
函数可以实现,但那是另一回事了。)