Oracle行转列是如何实现的
前言
最近公司项目上需要做个报表,有个很麻烦的需求就是SQL行转列,本来是一行行输出的SQL语句,现在需要将某个结果,横向展示出来,考虑到横向可能没有那么方便,需求还为了我们做了点让步,只需要转成10行就行,也就是说,我只需要将横向输出的10行转为10列就行了。
需求虽然简单,但是这SQL不太好写呀,而且异常的麻烦,我于是开始各种研究行转列的方式,下面就分享一下心得吧,SQL写得不算优雅,反正是为了实现需求而写的。
MAX 和 case when
select DISTINCT
temp.性状,
temp.酸碱度,
temp.硝酸盐,
temp.亚硝酸盐,
temp.氨,
temp.电导率,
temp.总有机碳,
temp.不挥发物,
temp.重金属,
temp.微生物限度
from
sample_demo ss
left join
(
select sdit.keyid1 as sampleid,
max(case when instr(sdit.namestr,'性状')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 性状,
max(case when instr(sdit.namestr,'酸碱度')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 酸碱度,
max(case when instr(sdit.namestr,'硝酸盐')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 硝酸盐,
max(case when instr(sdit.namestr,'亚硝酸盐')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 亚硝酸盐,
max(case when instr(sdit.namestr,'氨')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 氨,
max(case when instr(sdit.namestr,'电导率')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 电导率 ,
max(case when instr(sdit.namestr,'总有机碳')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 总有机碳 ,
max(case when instr(sdit.namestr,'不挥发物')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 不挥发物 ,
max(case when instr(sdit.namestr,'重金属')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 重金属 ,
max(case when instr(sdit.namestr,'微生物限度')>0 then (sdit.namestr ||' ' || sdit.nicknamestr) else '' end) as 微生物限度
from customer_st sdit
where sdit.sdcid = 'LEVEL'
and specs.important ='Y'
group by sdit.keyid1
) temp on temp.sampleid = ss.s_sampleid
where ss.nameid in ($P!{CAESER_LINKList})
首先要知道 left join 是通过关联将查询的数据进行拼接,然后使用select查询出想要的数据,结合case when找到指定的字段然后横向以列的形式展示,这种形式可以实现行转列,但是有一个很严重的问题就是如果字段名称是不确定的上面的SQL就用不了了,于是我开始从行数上面下手。
ROWNUM
Oracle里是没有像MySQL那样的LIMIT查询指定行的,于是想查询指定行就需要借助ROWNUM来实现
select
(
select namestr from
(
select ss.namestr,ROWNUM RMN from sample_demo ss
where ss.nameid in ($P!{SAPPHIRE_KEYID1List})
) where RMN=1
) as T1
from
sample_demo ss
where ss.nameid in ($P!{CAESER_LINKList})
其实就是先用一个select查询并且增加一个ROWNUM字段,外部在加一个select where去匹配ROWNUM没啥技术含量,但是我确实没有找到更合适的办法,目前为了尽快解决需求就只能这样了。
报表
再说说为什么这个报表要用这么麻烦的SQL,首先我们使用的是Jaspersoft工具来实现的报表,为的就是能将数据内容以固定的格式展示出来,我们通常的显示格式就是PDF,所以我们使用这个软件编辑jrxml文件来编写,这个报表就是一串xml只不过可以通过图形化进行操作,方便编辑
画报表最难的部分可能就是写SQL了吧,研究SQL的过程其实就是对数据库表结构进行探索的过程,有时候会发现如果知道了哪些字段在哪里,基本上对整个库表设计就有了清晰的认识了。
总结
因为疫情,很多时候都会陷入迷茫,只是在网上看到各种找不到工作的哀嚎,各种涌入送外卖的,送快递的人,实际上没发生在自己身上还真不能做到感同身受,但是我仍有很大的感触,所以我现在很珍惜自己的工作,也觉得有一份工作是挺不容易,有一份稳定的工作更是不容易。
加油!未来可期。
共同学习,写下你的评论
评论加载中...
作者其他优质文章