oracle语句属于中文如何转码,Oracle语句的再深化--转码

当我们面对一个数据表,且表结构为:

create table R_ExtSubFina_Month

(

rptdate date not null,

rptname varchar2(10) not null,

rptNum varchar2(10) not null,

SaleMoney number(18,3),

proMoney number(18,3),

,Status varchar2(2)

);

现在表中已经存在的数据如下(PS:这里的报送编码需要从别的表中获取):

0818b9ca8b590ca3270a3433284dd417.png

但是我们需要从当前表中统计出今年的本月,去年的本月和今年上个月的销售额和定金的数据,那么我们的sql语句应该怎么写??

方案一:union

我们都知道union是对表格进行联合查询的,当我们需要对两个表的数据进行查询我们可以使用,但是要遵守:

1.要求我们获取两个表的字段个数和字段数据类型是要完全一致的;

2.如果数据类型一致,但是个数不一致,我们可以对某个表中设计空字段,比如需要查询A表中的两个字段,需要B表中的1个字段,那么我们就要将语句这样写:

select * from A

union

select a, '  ' from B

此处的  ‘  ’ 就保证了A 和B表的字段数量一致;

但是我们的sql语句不单单是为了查询结果,对结果进行显示和分析,更重要的是性能;所以union不能入围我们的选择方案(具体原因稍后在方案2中讲解)

方案二:union all

使用union 需要将两个表的字段数量和字段的数据类型都一致,为了避免这种问题,我们使用union all,这样我们可以直接将上面的语句修改为:

select * from A  union all(select * from B);

虽然可以解决这个查询的问题,但是显示的结果中需要三个不同日期的结果,而这三个日期需要我们手动进行加减计算,然后再同一个表的同一个字段中取不同的值,那么问题来了,当我们使用union all  我们需要以每一个日期作为条件对表进行查询,这样就对表进行了至少三次的扫描,所以我们需要担心这样的语句带来的性能问题;

那么相比方案一我们有没有一些进步呢?答案是有的;

Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;

Union All:对两个结果集进行并集操作,包括重复行,不进行排序;

Union因为要进行重复值扫描,所以效率低。如果合并没有刻意要删除重复行,那么就使用Union All

方案三:decode转码求和

原理:我们将每一个日期作为条件一次性将所有的数据都查询出来,这样我们会查询出来三条数据,详细如下:

0818b9ca8b590ca3270a3433284dd417.png

我们可以发现红色框内的数据有为0的数据,这样我们想要的数据已经呈现出来,但是我们如何把三条数据合成一条(不含0)呢??

思路: 行专列-->decode-->求和

我们将上面的数据看成一个矩阵,矩阵行专列之后结果是不变的,所以上图中的数据就会变成下图中的数据:

0818b9ca8b590ca3270a3433284dd417.png

这样我们可以对每一列求和,然后和刚才的三个日期进行合并,这样三条数据就会被我们合成一条;

实现代码如下:

PS:参数设置:l_year :当前的年月 ; l_curLastMonth :今年的上个月;  l_lastYear :去年的这个月

select l_year year, l_curLastMonth lmon,l_lastYear lymon,

decode(A.rptdate,l_year,A.saleMoney ,0) AS ,

decode(A.rptdate, l_curLastMonth,A.saleMoney ,0) ASS,

decode(A.rptdate,l_lastYear,A.saleMoney ,0) ASSS

from A

到这里我们已经得到我们想要的数据,还挺简单的吧,以上只是一点小积累,有不对的地方欢迎大家指点。Oracle的sql语句正在进一步的总结,如果有什么好的建议或者意见请大家留言!!

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值