DB2逗号分隔输出
如何在DB2中的sql中获取逗号分隔的列值的内置函数,例如,如果存在具有该策略ID的列,并且它具有3行具有相同的id,但在三行中具有三个不同的angular色,那么它应该检索一行排“3,4,5”
例如
1. 4555 "2" 2. 4555 "3" 3. 4555 "4"
在一行DB2中输出4555 2,3,4
这正是你所需要的:
http://radheshk.blogspot.com/2008/02/sql-tips-techniques-string-aggregation.html
可悲的是,在DB2中无法轻松定义自定义集合函数(或者我不知道)。 所以我们必须求助于recursion查询,就像上面的例子。
解决这个问题的另一种方法涉及到游标,但这可能更糟糕…
LISTAGG函数是DB2 LUW 9.7中的新function
看例子:
create table myTable (id int, category int); insert into myTable values (1, 1); insert into myTable values (2, 2); insert into myTable values (5, 1); insert into myTable values (3, 1); insert into myTable values (4, 2);
例如:在分组列中select没有任何顺序
select category, LISTAGG(id, ', ') as ids from myTable group by category;
结果:
CATEGORY IDS --------- ----- 1 1, 5, 3 2 2, 4
例如:在分组列中selectorder by子句
select category, LISTAGG(id, ', ') WITHIN GROUP(ORDER BY id ASC) as ids from myTable group by category;
结果:
CATEGORY IDS --------- ----- 1 1, 3, 5 2 2, 4
根据您所拥有的DB2版本,您可以使用XML函数来实现这一点。
带有一些数据的示例表
create table myTable (id int, category int); insert into myTable values (1, 1); insert into myTable values (2, 2); insert into myTable values (3, 1); insert into myTable values (4, 2); insert into myTable values (5, 1);
使用xml函数汇总结果
select category, xmlserialize(XMLAGG(XMLELEMENT(NAME "x", id) ) as varchar(1000)) as ids from myTable group by category;
结果:
CATEGORY IDS -------- ------------------------ 1 <x>1</x><x>3</x><x>5</x> 2 <x>2</x><x>4</x>
使用replace使结果看起来更好
select category, replace( replace( replace( xmlserialize(XMLAGG(XMLELEMENT(NAME "x", id) ) as varchar(1000)) , '</x><x>', ',') , '<x>', '') , '</x>', '') as ids from myTable group by category;
清理结果
CATEGORY IDS -------- ----- 1 1,3,5 2 2,4
刚刚在这里看到了使用XMLTEXT而不是XMLELEMENT的更好的解决scheme。
我想用这个较小的查询,你可以做你想要的。 这相当于MySQL中的DB2的GROUP_CONCAT。
SELECT NUM, SUBSTR(xmlserialize(xmlagg(xmltext(CONCAT( ', ',ROLES))) as VARCHAR(1024)), 3) as ROLES FROM mytable GROUP BY NUM;
这将输出像这样的东西:
NUM ROLES ---- ------------- 1 111, 333, 555 2 222, 444
假设你的原始结果是这样的:
NUM ROLES ---- --------- 1 111 2 222 1 333 2 444 1 555
我的问题是用CSV转换行字段(CLOB)到列(VARCHAR),并使用转置表进行报告。 因为在报告层上转置会减慢报告速度。
一种方法是使用recursionSQL。 你可以find很多关于这方面的文章,但是如果你想join你所有的recursion转置列,那么它就会很困难和耗费资源。
我创build了多个全局临时表,我用一个关键标识符存储单个转置列。 最终,我有6个临时表join6列,但由于资源分配有限,我无法将所有列结合在一起。 我select了下面的3个公式,然后我只需要运行1个查询,这使得我在10秒内输出。
我发现了使用XML2CLOB函数的各种文章,并find了3种不同的方法。
REPLACE(VARCHAR(XMLAG)(XMLELEMENT(NAME“A”,ALIASNAME.ATTRIBUTENAME)))),'',',')AS TRANSPOSED_OUTPUT
NVL(TRIM(','FROM REPLACE(REPLACE(REPLACE(CAST(XML2CLOB(XMLAGG(XMLELEMENT(NAME“E”,ALIASNAME.ATTRIBUTENAME))AS VARCHAR(100)),'',''),'', ','),'','Nothing')),'Nothing')作为TRANSPOSED_OUTPUT
RTRIM(REPLACE(VARCHAR(XMLSERIALIZE(XMLAGEMENT(XMLELEMENT(NAME“A”,ALIASNAME.ATTRIBUTENAME)ORDER BY ALIASNAME.ATTRIBUTENAME)AS CLOB),'',','),'','') ,'',''))AS TRANSPOSED_OUTPUT
确保你将“ATTRIBUTENAME”转换为子查询中的varchar,然后在这里调用它。
其他的可能性,与recursioncte
with tablewithrank as ( select id, category, rownumber() over(partition by category order by id) as rangid , (select count(*) from myTable f2 where f1.category=f2.category) nbidbycategory from myTable f1 ), cte (id, category, rangid, nbidbycategory, rangconcat) as ( select id, category, rangid, nbidbycategory, cast(id as varchar(500)) from tablewithrank where rangid=1 union all select f2.id, f2.category, f2.rangid, f2.nbidbycategory, cast(f1.rangconcat as varchar(500)) || ',' || cast(f2.id as varchar(500)) from cte f1 inner join tablewithrank f2 on f1.rangid=f2.rangid -1 and f1.category=f2.category ) select category, rangconcat as IDS from cte where rangid=nbidbycategory
尝试这个:
SELECT GROUP_CONCAT( field1, field2, field3 ,field4 SEPARATOR ', ')