Pet*_*ter 1 sql db2 db2-400 ibm-midrange
我有一个简单的表格,数据如下:
col_1
==========
haddock
cod
hake
mackerel
tench
sprat
dace
rudd
pike
gudgeon
....
Run Code Online (Sandbox Code Playgroud)
我想选择数据,以便我可以输出5列:
col_1 col_2 col_3 col_4 col_5
======== ======== ======== ======== ========
haddock cod hake mackerel tench
sprat dace rudd pike gudgeon
...
Run Code Online (Sandbox Code Playgroud)
有一个很好的方法来做到这一点?NB iSeries DB2 SQL
为了显示正在发生的事情,我将使用"公共表表达式"在小的阶段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
Run Code Online (Sandbox Code Playgroud)
第一步为您提供中间结果
rn fish
====== ==========
0 haddock
1 cod
2 hake
3 mackerel
4 tench
5 sprat
6 dace
7 rudd
8 pike
9 gudgeon
Run Code Online (Sandbox Code Playgroud)
下一步给出
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
Run Code Online (Sandbox Code Playgroud)
然后我们根据列号将值扩展到单独的列
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
Run Code Online (Sandbox Code Playgroud)
最后一步用outrow数字将行挤压在一起
outrow col_1 col_2 col_3 col_4 col_5
====== ======== ======== ======== ======== ========
1 haddock cod hake mackerel tench
2 sprat dace rudd pike gudgeon
Run Code Online (Sandbox Code Playgroud)
当然,查询可能看起来像是一个很长的编写方式.我使用一个由不同的名字构建的表格进行了更大规模的测试.然后我缩小了语法.
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)
Run Code Online (Sandbox Code Playgroud)