为了账号安全,请及时绑定邮箱和手机立即绑定

Oracle行转列是如何实现的

标签:
Oracle

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的过程其实就是对数据库表结构进行探索的过程,有时候会发现如果知道了哪些字段在哪里,基本上对整个库表设计就有了清晰的认识了。

总结

图片描述
因为疫情,很多时候都会陷入迷茫,只是在网上看到各种找不到工作的哀嚎,各种涌入送外卖的,送快递的人,实际上没发生在自己身上还真不能做到感同身受,但是我仍有很大的感触,所以我现在很珍惜自己的工作,也觉得有一份工作是挺不容易,有一份稳定的工作更是不容易。
加油!未来可期。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
30
获赞与收藏
154

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消