使用iSeries DB2 SQL行到列

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

War*_*enT 5

为了显示正在发生的事情,我将使用"公共表表达式"在小的阶段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)