web-dev-qa-db-ja.com

グループごとのDB2カンマ区切り出力

DB2 SQLにカンマ区切りの列値の組み込み関数はありますか?

例:IDの列があり、同じIDの3つの行があるが、3つの異なる役割がある場合、データはコンマで連結する必要があります。

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

出力は、行ごとに次のようになります。

4555 2,3,4

19
gaurav

[〜#〜] 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
35
Fernando

この小さなクエリで、思い通りのことができると思います。これは、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
10
Nicki Voutou

使用している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

XMLELEMENT here の代わりにXMLTEXTを使用したより良いソリューションを見ただけです。

8
boes

DB2 9.7.5以降、そのための関数があります。

LISTAGG(colname, separator)

詳細については、これを確認してください: LISTAGGを使用してデータの行をカンマ区切りリストに変換する

1
Gomez NL

私の問題は、CSVで行フィールド(CLOB)を列(VARCHAR)に転置し、転置されたテーブルをレポートに使用することでした。レポートレイヤーで転置すると、レポートの速度が低下するためです。

移動する1つの方法は、再帰的SQLを使用することです。それに関する多くの記事を見つけることができますが、すべての再帰的な転置列を結合したい場合は、困難でリソースを消費します。

複数のグローバル一時テーブルを作成し、1つのキー識別子を持つ単一の転置列を格納しました。結局、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(XMLAC(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 AS CLOB))、 ''、 '、')、 ' '、' ')、' '、' '))AS TRANSPOSED_OUTPUT 

サブクエリで "ATTRIBUTENAME"をvarcharにキャストしてから、ここで呼び出していることを確認してください。

0
Bhavesh

その他の可能性、再帰的な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
0
Esperento57