Linux命令如何将竖行改成横行,用DECODE和CASE WHEN将多行单列数据改为单行多列数据(即竖向排列改为横向排列)...

1、几天前,终于修改了SQL查询语句,改为适应报表格式。其中最关键的就是用DECODE和CASE WHEN方式,只要查询结果正确,那么用这两种方式,基本上想要什么格式就可以拿到什么格式。

2、DECODE函数使用:

格式是  DECODE(表字段名,‘数值1’,‘数值2’,‘数值3’,‘数值4’,‘数值5’)。

具体含义:这个函数,实际作用的是,检查指定的表字段,如果字段值=数值1,那么就返回数值2,如果字段值=数值3,那么返回数值4,如果字段值不等于数值1也不等于数值3,那么就返回数值5 。也许前面的表述,说的不那么清楚,就请看下面的示例:

示例表student_arhievement:

student_name

student_arhievement

black

80

jhon

40

jack

80

pher

40

clear

80

ruini

70

pull

30

ada

30

boen

50   select student_arhievement, decode(student_arhievement,'80','pass A','70','pass B','fail') from student_arhievement;

查询结果应该是:

black

pass A

jhon

fail

jack

pass A

pher

fail

clear

pass A

ruini

pass B

pull

fail

ada

fail

boen

fail

这个查询结果应该是很明显了,注意哈,这个查询结果,我是没有经过测试的,有可能出错,也有可能是对的。

我把查询语句改成:

select decode(student_arhievement,'80','pass','70','pass','fail'),count(*) from student_arhievement group by decode(student_arhievement,'80','pass','70','pass','fail') ;

查询结果应该是:

pass 4

fail   5

这里,我在画蛇添足一下,查询语句改成这样:

break on dummy;

compute sum label totalcount of count on dummy;

select null dummy,decode(student_arhievement,'80','pass','70','pass','fail'),count(*) count from student_arhievement group by decode(student_arhievement,'80','pass','70','pass','fail') ;

查询结果是:

pass 4

fail    5

total               9

这个可以给出一个汇总行,就是最后的total行,很不错的东西。

请注意最后的语句,这里有个技巧,就是那个null dummy,其实就是一个伪列,字段名为dummy,但是却没有值,所以pass行和fail行的前几个字段位置上全是空格,因为是NULL,当然就不显示了。经过实际测试,还要注意,dummy伪列的列宽度,因为没有值,所以SQLPLUS会将这个列的宽度定义为1个字符位置,结果导致显示如下:

pass 4

fail    5

t              9

就是最后的汇总行,只显示了一个T,其实就是TOTAL的第一个字符,因为列宽度不够,所以只显示T。办法就是在语句前面增加一个column dummy format a5就可以了。

关于BREAK和COMPUTR,我估计还需要另外一篇文章来专门写,内容比较多。

3、CASE WHEN函数

相对来说,DECODE 函数已经很强大了,但是CASE WHEN函数还要强大的多。

DECODE 函数主要作用是,根据给定的值的要求,就是比如如果字段值是A,那么函数返回就是1,如果字段值是B,那么返回就是2,这个比较适合指定的字段值,有明显的少量基数,就是字段值比较像男女性别这个值,只有男、女或者未知等,但是如果指定的字段值,没有这样的基数,数值全是乱的,从1到100全有,那么用DECODE就很不方便了,这时候CASE WHEN就会方便很多。

CASE WHEN格式:

CASE WHEN 表达式 THEN 返回值1 ELSE 返回值2 END;

这个函数,有一部分功能是和DECODE函数一样的。

仔细看看下面两个:

decode(archivement ,'80’,'pass’,'fail’)

case when arvhivement='80' then 'pass' else 'fail' end

上面这两句,结果是一样的。但是CASE WHEN功能更强。

看下面的表studentu_archievement:

student_name

student_arhievement

black

81

jhon

43

jack

87

pher

35

clear

98

ruini

67

pull

49

ada

89

boen

61

这表中所有同学的成绩全部不一样,这时候用DECODE处理就会很麻烦,CASE WHEN很好用。可以这样写:

select case when student_archievement>60 then 'pass' else 'fail' end,count(*) from student_archievement

group by case when student_archievement>60 then 'pass' else 'nopass' end ;

查询结果:

pass 6

fail    3

这样处理起来就比DECODE要强多了,语句看起来也要简单的很多。

4、竖排变横排的作法

其实,这种竖排变横排的查询需求,有一部分是业务系统没有做好。

看示例表 student_archievement:

student_name

student_class

student_archievement

jack

Mathematics

98

jack

Chinese

67

jack

English

82

ada

Mathematics

78

ada

Chinese

89

ada

English

91

jhon

Mathematics

81

jhon

Chinese

85

jhon

English

79

从某种意义上讲,这样的表结构很不理想,但是实际情况中,有很多这样的表结构。

现在需要把查询结果改成一行就是一个人的3门课的成绩,比如像这样:jack 98 67 82。

处理办法可以这样写:

select student_name,

sum(decode(student_class,'Mathematics',student_archievement)) Mathematics,

sum(decode(student_class,'Chinese',student_archievement)) Chinese,

sum(decode(student_class,'English',student_archievement)) English

from student_archievement

group by student_name;

这句话的执行结果就是:

student_name

Mathematics

Chinese

English

jack

98

67

82

ada

78

89

91

jhon

81

85

79

这样的查询结果,看起来就会舒服很多。

因为文章中的示例数据太过简单了,所以没有办法记录更复杂的计算办法,这里就只写一些相对简单的,以后再进一步添加。

我这里只用到了DECODE函数,当然还是可以用CASE WHEN来做,只是CASE WHEN语句相对复杂点,长度较长而已

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值