如何在DB2中的sql 中爲逗號分隔列值獲取內置函數,例如,如果存在具有此策略ID的列,並且它具有3行具有相同ID但在三行中具有三個不同角色的行,那麼它應該檢索一行中的行「3,4,5」DB2逗號分隔輸出
例如
1. 4555 "2"
2. 4555 "3"
3. 4555 "4"
輸出4555 2,3,4
在DB2一行
如何在DB2中的sql 中爲逗號分隔列值獲取內置函數,例如,如果存在具有此策略ID的列,並且它具有3行具有相同ID但在三行中具有三個不同角色的行,那麼它應該檢索一行中的行「3,4,5」DB2逗號分隔輸出
例如
1. 4555 "2"
2. 4555 "3"
3. 4555 "4"
輸出4555 2,3,4
在DB2一行
這是你需要的東西:
http://radheshk.blogspot.com/2008/02/sql-tips-techniques-string-aggregation.html
可悲的是,沒有在DB2中輕鬆定義自定義集合函數的方法(或不是我知道的帽子)。所以我們必須求助於遞歸查詢,就像上面的例子。
另一種方式來解決這個問題涉及光標,但可能是更糟......
試試這個:
SELECT GROUP_CONCAT(field1, field2, field3 ,field4 SEPARATOR ', ')
會出現什麼這裏是field1 – gaurav
Field1:1.4555 - SELECT GROUP_CONCAT(field1,,field3,field4 SEPARATOR',') –
Ca ñ你請建立你的問題?:D –
取決於你有,你可以使用XML函數來實現這一目標的DB2版本。
示例表的一些數據
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 here一個更好的解決方案。
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
例如:在分組列由子句選擇具有順序
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中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
assumming原來的結果是類似的東西:
NUM ROLES
---- ---------
1 111
2 222
1 333
2 444
1 555
我的問題是要轉的行字段(CLOB)列(VARCHAR )與CSV並使用轉置表進行報告。因爲在報告層上轉置會減慢報告速度。
一種方法是使用遞歸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') as TRANSPOSED_OUTPUT
RTRIM(REPLACE(REPLACE(REPLACE(VARCHAR(XMLSERIALIZE(XMLAGG(XMLELEMENT(NAME "A",ALIASNAME.ATTRIBUTENAME) ORDER BY ALIASNAME.ATTRIBUTENAME) AS CLOB)), '',','),'',''),'','')) AS TRANSPOSED_OUTPUT
確保您鑄造你的 「ATTRIBUTENAME」 爲varchar在子查詢中,然後在這裏調用它。
另一種可能性,遞歸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
由於DB2 9.7.5存在的一個功能:
LISTAGG(colname, separator)
檢查這個以瞭解更多信息:Using LISTAGG to Turn Rows of Data into a Comma Separated List
感謝您的答案 – gaurav