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 

根据您所拥有的DB​​2版本,您可以使用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 ', ')