我有一个简单的表格,数据如下:
col_1
==========
haddock
cod
hake
mackerel
tench
sprat
dace
rudd
pike
gudgeon
....
我想选择数据,以便我可以将其输出为5列:
col_1 col_2 col_3 col_4 col_5
======== ======== ======== ======== ========
haddock cod hake mackerel tench
sprat dace rudd pike gudgeon
...
有一个很好的方法吗? NB iSeries DB2 SQL
答案 0 :(得分:5)
为了显示正在发生的事情,我将在“a-table table expressions”的小阶段a,b,c,......中将其分解,但这是一个SELECT语句
with a as
( select row_number() over(order by order of f) - 1 as nb,
col_1 as fish
from fishtable as f
), b as
( select smallint(nb/5)+1 as outrow,
smallint(mod(nb),5)+1 as outcol,
col_1 as fish
from a
), c as
( select outrow,
(case when outcol=1 then fish else null end) as fish1,
(case when outcol=2 then fish else null end) as fish2,
(case when outcol=3 then fish else null end) as fish3,
(case when outcol=4 then fish else null end) as fish4,
(case when outcol=5 then fish else null end) as fish5
from b
)
select outrow,
max(fish1) col_1,
max(fish2) col_2,
max(fish3) col_3,
max(fish4) col_4,
max(fish5) col_5
from c
group by outrow
order by outrow
第一步为您提供
的中间结果 rn fish
====== ==========
0 haddock
1 cod
2 hake
3 mackerel
4 tench
5 sprat
6 dace
7 rudd
8 pike
9 gudgeon
下一步是
outrow outcol fish
====== ====== ==========
1 1 haddock
1 2 cod
1 3 hake
1 4 mackerel
1 5 tench
2 1 sprat
2 2 dace
2 3 rudd
2 4 pike
2 5 gudgeon
然后我们根据列号
将值扩展到单独的列outrow fish1 fish2 fish3 fish4 fish5
====== ======== ======== ======== ======== ========
1 haddock
1 cod
1 hake
1 mackerel
1 tench
2 sprat
2 dace
2 rudd
2 pike
2 gudgeon
最后一步用outrow number
将行挤压在一起outrow col_1 col_2 col_3 col_4 col_5
====== ======== ======== ======== ======== ========
1 haddock cod hake mackerel tench
2 sprat dace rudd pike gudgeon
当然,查询可能看起来像编写它的方式相当长。我使用一个由不同的名字构建的表格进行了更大规模的测试。然后我缩小了语法。
select max(case when mod(rn,5)=0 then fname else null end) fname1
,max(case when mod(rn,5)=1 then fname else null end) fname2
,max(case when mod(rn,5)=2 then fname else null end) fname3
,max(case when mod(rn,5)=3 then fname else null end) fname4
,max(case when mod(rn,5)=4 then fname else null end) fname5
from (select fname, row_number() over(order by order of f)-1 as rn
from firstnames f
) as a
group by int(rn/5)
order by int(rn/5)
答案 1 :(得分:0)
您是否真的想要单独的COLUMNS,或者只是希望数据是包含五行值的单个列。如果你想要后者,请尝试以下方法:
SELECT GROUP_CONCAT( a.col_1 SEPARATOR ' ' )
FROM (SELECT ( (@ROWNUM := CASE WHEN @ROWNUM IS NULL THEN 0 ELSE @ROWNUM + 1 END) DIV 5 ) AS group_num, col_1
FROM your_table) a
GROUP BY a.group_num;
如果你想要前者,那就像:
SELECT GROUP_CONCAT( CASE WHEN a.row_num MOD 5 = 0 THEN a.col_1 ELSE '' END SEPARATOR '' ) AS col_1
,GROUP_CONCAT( CASE WHEN a.row_num MOD 5 = 1 THEN a.col_1 ELSE '' END SEPARATOR '' ) AS col_2
,GROUP_CONCAT( CASE WHEN a.row_num MOD 5 = 2 THEN a.col_1 ELSE '' END SEPARATOR '' ) AS col_3
,GROUP_CONCAT( CASE WHEN a.row_num MOD 5 = 3 THEN a.col_1 ELSE '' END SEPARATOR '' ) AS col_4
,GROUP_CONCAT( CASE WHEN a.row_num MOD 5 = 4 THEN a.col_1 ELSE '' END SEPARATOR '' ) AS col_5
FROM (SELECT @ROWNUM := CASE WHEN @ROWNUM IS NULL THEN 0 ELSE @ROWNUM + 1 END AS row_num, col_1
FROM your_table) a
GROUP BY a.row_num DIV 5;
请参阅http://sqlfiddle.com/#!2/7dc42/9
上的SQLFiddle很抱歉,您刚刚注意到您正在寻找iSeries DB2 SQL(而不是MySQL)的解决方案。 DB2需要一个不同的解决方案。
如果你有DB2 LISTAGG功能,你可以尝试类似的东西(抱歉没有办法测试它,所以它可能不完美):
SELECT LISTAGG( CASE WHEN MOD(a.row_num, 5) = 0 THEN a.col_1 ELSE '' END, '' ) AS col_1
,LISTAGG( CASE WHEN MOD(a.row_num, 5) = 1 THEN a.col_1 ELSE '' END, '' ) AS col_2
,LISTAGG( CASE WHEN MOD(a.row_num, 5) = 2 THEN a.col_1 ELSE '' END, '' ) AS col_3
,LISTAGG( CASE WHEN MOD(a.row_num, 5) = 3 THEN a.col_1 ELSE '' END, '' ) AS col_4
,LISTAGG( CASE WHEN MOD(a.row_num, 5) = 4 THEN a.col_1 ELSE '' END, '' ) AS col_5
FROM (SELECT ROW_NUMBER() AS row_num, col_1
FROM your_table) a
GROUP BY INT(a.row_num / 5);
注意:
1)使用LISTAGG(如XMLAGG)还有其他选择。在此论坛中搜索DB2 GROUP_CONCAT替代方案。有很多例子。
2)如果您没有可用的ROW_NUMBER(),可以使用递归SQL在DB2中进行模拟。
答案 2 :(得分:0)
我有一个似乎有效的解决方案,虽然不是很优雅:
with tab1 as ( select col_1 as col_1 from my_table a where mod(rrn(a), 5) = 1 ),
with tab2 as ( select col_1 as col_1 from my_table a where mod(rrn(a), 5) = 2 ),
with tab3 as ( select col_1 as col_1 from my_table a where mod(rrn(a), 5) = 3 ),
with tab4 as ( select col_1 as col_1 from my_table a where mod(rrn(a), 5) = 4 ),
with tab5 as ( select col_1 as col_1 from my_table a where mod(rrn(a), 5) = 0 )
select tab1.col_1 as col_1,
tab2.col_1 as col_2,
tab3.col_1 as col_3,
tab4.col_1 as col_4,
tab5.col_1 as col_5
from tab1 LEFT JOIN tab2 on rrn(tab1) + 1 = rrn(tab2)
LEFT JOIN tab3 on rrn(tab2) + 1 = rrn(tab3)
LEFT JOIN tab4 on rrn(tab3) + 1 = rrn(tab4)
LEFT JOIN tab5 on rrn(tab4) + 1 = rrn(tab5)
答案 3 :(得分:0)
IBMi SQL参考(v7r3)中的示例:
按字母顺序生成逗号分隔名称列表,按部门分组:
SELECT工作部门, LISTAGG(姓氏,‘,’)WITHIN GROUP(ORDER BY姓氏) AS员工 来自emp GROUP BY工作部门;
产生以下结果:
工作场所员工
A00 HAAS,HEMMINGER,LUCCHESSI,O'CONNELL,ORLANDO
B01汤普森
C01 KWAN,NATZ,NICOLLS,QUINTANA .....
清洁,有效。