在实际工作当中,有很多主从关系表需要在一个列表展示成一行数据,从表数据多列转成一行。vm_contact()和listagg()函数都能实现列转行功能。
1、vm_concat使用情况:
根据主表ID,查询从表ID列
select t.id,wm_concat(t1.id) as detailsId
from t_test t
left join t_test_detail t1 on t.id = t1.set_id
group by t.id
返回结果,在oracle11g中返回clob类型,在oracle10g中返回varchar型。我本机装的11g,上面这种写法就直接报错。

转成to_char正常页面正常。
select t.id,to_char(wm_concat(t1.id)) as detailsId
from t_test t
left join t_test_detail t1 on t.id = t1.set_id
group by t.id
运行结果

2、listagg使用
LISTAGG(Item_Name, ',') WITHIN GROUP(ORDER BY Item_Name) -- 将 Item_Name 列的内容以", "进行分割合并、排序;
实例:
select t.id,listagg(t1.id,',')within group(order by t1.id) as detailsId
from t_test t
left join t_test_detail t1 on t.id = t1.set_id
group by t.id
运行结果

---------------------------------------------------分割线-------------------------------------------------------
在实际应用中,联查表的时候用vm_contact(),从表没有数据时,转成clob类型报错。报错如下

最后将vm_contract()改成listagg()解决问题,特此记录。
本文介绍了在Oracle数据库中,如何使用vm_concat和listagg函数将从表的多列数据转换为一行。vm_concat在不同版本可能返回不同类型,可能会导致报错,而listagg能稳定地按指定分隔符合并列并排序。当从表无数据时,vm_concat会返回CLOB类型引发错误,此时可以改用listagg来解决该问题。

被折叠的 条评论
为什么被折叠?



