24

中是否有用于逗号分隔列值的内置函数DB2 SQL

示例:如果有带有 an 的列,ID并且它有 3 行相同ID但具有三个不同的角色,则数据应该用逗号连接。

ID   | Role
------------
4555 | 2
4555 | 3
4555 | 4

每行的输出应如下所示:

4555 2,3,4

4

7 回答 7

44

LISTAGG函数是 DB2 LUW 9.7 中的新函数

见例子:

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 category, LISTAGG(id, ', ') as ids from myTable group by category;

结果:

CATEGORY  IDS
--------- -----
1         1, 5, 3
2         2, 4

示例:在分组列中使用 order 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
于 2014-01-24T16:06:30.840 回答
10

我认为通过这个较小的查询,你可以做你想做的事。这相当于 DB2 中 MySQL 的 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
于 2015-02-12T13:02:04.727 回答
9

根据您拥有的 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>

使用替换使结果看起来更好

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 的更好解决方案。

于 2011-09-01T15:27:37.693 回答
3

从 DB2 9.7.5 开始,有一个功能:

LISTAGG(colname, separator)

检查此以获取更多信息:使用 LISTAGG 将数据行转换为逗号分隔列表

于 2017-12-06T08:41:16.000 回答
0

其他可能性,使用递归 cte

    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
于 2016-10-23T18:40:32.513 回答
0

我的问题是使用 CSV 将行字段(CLOB)转置为列(VARCHAR),并使用转置表进行报告。因为在报表层上转置会减慢报表的速度。

一种方法是使用递归 SQL。您可以找到很多关于此的文章,但如果您想加入所有递归转置列,那么它既困难又耗费资源。

我创建了多个全局临时表,在其中存储了带有一个键标识符的单个转置列。最终,我有 6 个临时表用于连接 6 个列,但由于资源分配有限,我无法将所有列放在一起。我选择了以下 3 个公式,然后我只需要运行 1 个查询,它会在 10 秒内给我输出。

我找到了有关使用 XML2CLOB 函数的各种文章,并找到了 3 种不同的方法。

REPLACE(VARCHAR(XML2CLOB(XMLAGG(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(REPLACE(REPLACE(VARCHAR(XMLSERIALIZE(XMLAGG(XMLELEMENT(NAME "A",ALIASNAME.ATTRIBUTENAME) ORDER BY ALIASNAME.ATTRIBUTENAME) AS CLOB)), '',','),'','') ,'','')) 作为 TRANSPOSED_OUTPUT

确保在子查询中将“ATTRIBUTENAME”转换为 varchar,然后在此处调用它。

于 2016-01-29T18:32:07.460 回答
-2

尝试这个:

SELECT GROUP_CONCAT( field1, field2, field3 ,field4 SEPARATOR ', ')
于 2011-08-25T10:50:46.823 回答