政府机关

db2 中如何用 SQL 语句的方式实现行列转换。

如 a,1
b,2

转换为
a,b
1,2
参与13

12同行回答

wencycoolwencycool数据库管理员山东
矩阵转换的 数据库做起来确实稍微麻烦一点点,用sas或者R软件。就方便多了,很简单。不知道zeng版是否接受。显示全部
矩阵转换的 数据库做起来确实稍微麻烦一点点,用sas或者R软件。就方便多了,很简单。不知道zeng版是否接受。收起
互联网服务 · 2013-06-21
浏览787
hczzhonghczzhong售前工程师CN
回复 11# leo UDF can c code,技术本身不是问题,代码质量才是:)显示全部
回复 11# leo

UDF can c code,技术本身不是问题,代码质量才是:)收起
IT分销/经销 · 2013-06-21
浏览811
leo_wynleo_wyn商业智能工程师Security
回复 10# hczzhong     是啊, 你提到的排序问题我也曾经遇到过,解决的方法是采用“row_number() 分析函数”, 转换前人为的排序(order by 的操作都是最后处理,所以不能改变转换前的顺序)    UDF扩展性更好,但性能往往不能保证了...显示全部
回复 10# hczzhong


    是啊, 你提到的排序问题我也曾经遇到过,解决的方法是采用“row_number() 分析函数”, 转换前人为的排序(order by 的操作都是最后处理,所以不能改变转换前的顺序)

    UDF扩展性更好,但性能往往不能保证了收起
系统集成 · 2013-06-21
浏览802
hczzhonghczzhong售前工程师CN
回复 9# leo string长度有限。不过这种行列转换最多就能搞出1K来行,没准能用用,尤其要转成表时。没有listagg时可以有UDF这种转换本身的限制多,列数,结果集不保证次序(除非有确保次序的排序),最后的结果还是应用逐列处理合适。查询时的排序保证行的内容,逐列处理才能确保行的次序...显示全部
回复 9# leo
string长度有限。不过这种行列转换最多就能搞出1K来行,没准能用用,尤其要转成表时。
没有listagg时可以有UDF
这种转换本身的限制多,列数,结果集不保证次序(除非有确保次序的排序),最后的结果还是应用逐列处理合适。查询时的排序保证行的内容,逐列处理才能确保行的次序,才像矩阵转换。收起
IT分销/经销 · 2013-06-21
浏览824
leo_wynleo_wyn商业智能工程师Security
回复 8# hczzhong     listagg() 是oracle 11g中函数, db2 v10 将其“兼容过来” 这个函数使用很方便    此外还有 wmsys.wm_concat() 这样的非"公版"函数(字符串总长度超过30k)都能实现类似的功能!    xmlagg 和 递归的方法更适用于 v9 的 ...显示全部
回复 8# hczzhong


    listagg() 是oracle 11g中函数, db2 v10 将其“兼容过来” 这个函数使用很方便

    此外还有 wmsys.wm_concat() 这样的非"公版"函数(字符串总长度超过30k)都能实现类似的功能!

    xmlagg 和 递归的方法更适用于 v9 的 版本收起
系统集成 · 2013-06-21
浏览828
hczzhonghczzhong售前工程师CN
数据库列数是有限制的,如果行列转换到关系模型,需要知道行数,列数,排序,否则,可能每次结果都不一样,并且能转换的行数多不了,最大1012*1012的矩阵with tmp1(c1,c2) as (values('a',1),('b',2),('c',3)),tmp2(c1,c2) as (select listagg(c1,',') within group (order by c2),lista...显示全部
数据库列数是有限制的,如果行列转换到关系模型,需要知道行数,列数,排序,否则,可能每次结果都不一样,并且能转换的行数多不了,最大1012*1012的矩阵
with tmp1(c1,c2) as (values('a',1),('b',2),('c',3)),
tmp2(c1,c2) as (
select listagg(c1,',') within group (order by c2),listagg(c2,',')  within group (order by c2) from tmp1 group by 1),
tmp3(c1) as (
select T.c4 from tmp2,lateral(values(tmp2.c1),(tmp2.c2)) as T(c4) group by T.c4 having count(*) >0)
select trim(substr(c1,1,instr(c1,',')-1)) ,trim(substr(c1,instr(c1,',',1,1) +1, instr(c1,',',1,2)-instr(c1,',',1,1)-1)) ,trim(substr(c1,instr(c1,',',1,2) +1, length(c1)-instr(c1,',',1,2))) from tmp3;
仅仅输出的话,转换结果行数多不了,因为最多列数有限制,listagg到varchar查询倒是可以快点,不过很容易行的长度超出,转成CLOB也多不了几行。
with tmp1(c1,c2) as (values('a',1),('b',2),('c',3)),
tmp2(c1,c2) as (
select listagg(c1,',') within group (order by c2),listagg(c2,',')  within group (order by c2) from tmp1 group by 1)
select T.c3 from tmp2,lateral(values(tmp2.c1),(tmp2.c2)) as T(c3) group by T.c3 having count(*) >0;
xmlagg输出数据类型是XML,能装比较多的行。聚集成一行,然后按列输出,或者用syscat.columns数据拼union all,不会有很多的额外操作。收起
IT分销/经销 · 2013-06-20
浏览890
macrozengmacrozeng数据库管理员IBM
谢谢 Leo ,表的行列数是不确定的,同时能兼顾性能就更好了显示全部
谢谢 Leo ,表的行列数是不确定的,同时能兼顾性能就更好了收起
政府机关 · 2013-06-20
浏览817
leo_wynleo_wyn商业智能工程师Security
回复 1# macrozeng 由于列数目前是2列,所以我用了UNION ALL,这部分暂时还不能动态化,以上语句在v9 一以上版本都能测试通过如果是v9.7以上的,还可以使用更好的方法显示全部
回复 1# macrozeng


由于列数目前是2列,所以我用了UNION ALL,这部分暂时还不能动态化,以上语句在v9 一以上版本都能测试通过

如果是v9.7以上的,还可以使用更好的方法收起
系统集成 · 2013-06-20
浏览830
leo_wynleo_wyn商业智能工程师Security
WITH tmp (f1, f2) AS (VALUES ('a', 1), ('b', 2), ('c', 3))SELECT SUBSTR (          XMLSERIALIZE (             XMLAGG (XMLTEXT (f1 || ',') ORDER BY f2) AS CLOB (1 M)),   &...显示全部
WITH tmp (f1, f2) AS (VALUES ('a', 1), ('b', 2), ('c', 3))
SELECT SUBSTR (
          XMLSERIALIZE (
             XMLAGG (XMLTEXT (f1 || ',') ORDER BY f2) AS CLOB (1 M)),
          1,
          50)
          AS pivot_f1
  FROM tmp
UNION ALL
SELECT SUBSTR (
          XMLSERIALIZE (
             XMLAGG (XMLTEXT (f2 || ',') ORDER BY f2) AS CLOB (1 M)),
          1,
          50)
  FROM tmp收起
系统集成 · 2013-06-20
浏览830
jimmyjimmy数据仓库工程师招行软件中心
case when 吧不过这个是固定列数的显示全部
case when 吧
不过这个是固定列数的收起
银行 · 2013-06-20
浏览857

提问者

macrozeng
数据库管理员IBM

问题状态

  • 发布时间:2013-06-20
  • 关注会员:1 人
  • 问题浏览:14751
  • 最近回答:2013-06-21
  • X社区推广