SQL行列转换实战

本文介绍如何使用SQL中的decode和case语句实现数据的行列转换、条件筛选及报表生成等实用技巧。通过具体实例展示了如何将单一结构的数据转化为复杂报表形式,并提供了多种条件判断的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

None.gif行列转换实例
None.gif                  表ttt有三个字段
None.gif                  seq  
--序列
None.gif
                  jcxm --检查项目
None.gif
                  zhi  --
None.gif

None.gif                  数据分别如下:
None.gif                  seq   jcxm       zhi
None.gif                  
-------      --------          --------
None.gif
                  11     1    0.50
None.gif                  
11     2    0.21
None.gif                  
11     3    0.25
None.gif                  
12     1    0.24
None.gif                  
12     2    0.30
None.gif                  
12     3    0.22                             
None.gif
None.gif                  实现功能
None.gif                  创建视图时移动行值为列值
None.gif
None.gif
None.gif                  
create view v_view1
None.gif                  
as
None.gif                  
select seq,
None.gif                         
sum(decode(jcxm,1, zhi)) 检测项目1,
None.gif                         
sum(decode(jcxm,2, zhi)) 检测项目2, 
None.gif                         
sum(decode(jcxm,3, zhi)) 检测项目3 
None.gif                  
from ttt
None.gif                  
group by seq;
None.gif
None.gif                  序号 检测项目1  检测项目2  检测项目3
None.gif                  
11     0.50    0.21     0.25
None.gif                  
12     0.24    0.30     0.22
None.gif
None.gif 
None.gif
None.gif                  技巧:
None.gif                  用THEN中的0和1来进行统计(
SUM
None.gif
None.gif                  jcxm   zhi
None.gif                  
----   ----
None.gif
                  a           1
None.gif                  b           
1
None.gif                  a           
3
None.gif                  d           
2
None.gif                  e           
4
None.gif                  f           
5
None.gif                  a           
5
None.gif                  d           
3
None.gif                  d           
6
None.gif                  b           
5
None.gif                  c           
4
None.gif                  b           
3
None.gif                  求他的zhi既是1,也是3,也是5的jcxm
None.gif                  方法一
None.gif                  
select jcxm
None.gif                  
from ttt
None.gif                  
group by jcxm
None.gif                  
having sum(decode(zhi,1,-1,3,-1,5,-1,0)) = -3
None.gif                  方法二
None.gif                  
select jcxm from ttt 
None.gif                  
group by jcxm having (sign(sum(decode(zhi,1,-1,0)))+
None.gif                  
sign(sum(decode(zhi,3,-1,0)))+sign(sum(decode(zhi,5,-1,0)))<=-3);
None.gif
None.gif                  
----------
None.gif
                  a
None.gif                  b
None.gif                  说明:
None.gif                  
sign()函数根据某个值是0、正数还是负数,分别返回0、1-1
None.gif                  所以可以用sign和decode来完成比较字段大小来区某个字段
None.gif                  
select decode(sign(字段1-字段2),-1,字段3,字段4) from dual;
None.gif
None.gif                  sign是一个对于写分析SQL有很强大的功能
None.gif                  下面我对sign进行一些总结:
None.gif                  但属性student取0和1以外的值,或者student取两个以上的标法值,问题就不会这么简单了
None.gif                  解决办法就是特征函数(
abs(),sign())
None.gif
None.gif                  常用的特征算法
None.gif                  [A=B]=
1abssign(A-B))
None.gif                  [A!=B]=
abssign(A-B)) 
None.gif                  [A
<B]=1sign1sign(A-B)) 
None.gif                  不能用
-sign(A-B):因为如果不满足A<b则返回-1,而不是0,这样就不能用在字段选择上了
None.gif                  [A
<=B]=sign(1sign(A-B))
None.gif                  [A
>B]=1sign1sign(A-B))
None.gif                  [A
>=B]=sign(1sign(A-B)))
None.gif                  [NOTα]=
1-d [α]
None.gif                  [αANDb ]=d [α]
*d [b ] (6)
None.gif                  [αOR b ]=
sign(d [α]+d []
None.gif
None.gif                  例如:
None.gif                  A
<B                         Decode( Sign(A-B), -110 )      
None.gif                     
None.gif                  A
<=B                         Decode( Sign(A-B), 101 )      
None.gif                     
None.gif                  A
>B                         Decode( Sign(A-B), 110 )       
None.gif                    
None.gif                  A
>=B                         Decode( Sign(A-B), -101 )     
None.gif                      
None.gif                  A
=B                         Decode( A, B, 10 )         
None.gif                  A 
between B and C      Decode( Sign(A-B), -10
None.gif                  Decode(
Sign(A-C), 101 ))         
None.gif                  A 
is null                       Decode(A,null,1,0)         
None.gif                  A 
is not null                 Decode(A,null,0,1)         A in 
None.gif                  (B1,B2,dot.gif,Bn)  Decode(A,B1,
1,B2,1,dot.gif,Bn,1,0)         
None.gif                  nor LogA                    Decode( LogA, 
010 )            
None.gif                    (
1-Sign(LogA)) 
None.gif                  LogA 
and LogB            LogA * LogB 
None.gif                  LogA 
or LogB              LogA + LogB 
None.gif                  LogA xor LogB            Decode(
Sign(LogA),Sign(LogB),0,1)    
None.gif                  Mod(
Sign(LogA),Sign(LogB),2
None.gif
None.gif
None.gif                  
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif
None.gif                  
[NextPage]
None.gif                  另外一个关于成绩的分析例子
None.gif
None.gif                  
SELECT
None.gif                  
SUM(CASE WHEN cj <60 THEN 1 ELSE 0 ENDas "not passed",
None.gif                  
SUM(CASE WHEN cj BETWEEN 60 AND 79 THEN 1 ELSE 0 ENDas 
None.gif                  "passed",
None.gif                  
SUM(CASE WHEN cj BETWEEN 80 AND 89 THEN 1 ELSE 0 ENDas 
None.gif                  "good",
None.gif                  
SUM(CASE WHEN cj >=90 THEN 1 ELSE 0 ENDas "Excellent"
None.gif                  
FROM cjtable;
None.gif
None.gif                  decode用法2
None.gif                  表、视图结构转化
None.gif                  现有一个商品销售表sale,表结构为:
None.gif                  
month    char(6)      --月份
None.gif
                  sell    number(10,2)    --月销售金额
None.gif

None.gif                  现有数据为:
None.gif                  
200001  1000
None.gif                  
200002  1100
None.gif                  
200003  1200
None.gif                  
200004  1300
None.gif                  
200005  1400
None.gif                  
200006  1500
None.gif                  
200007  1600
None.gif                  
200101  1100
None.gif                  
200202  1200
None.gif                  
200301  1300
None.gif
None.gif                  想要转化为以下结构的数据:
None.gif                  
year   char(4)          --年份
None.gif
                  ------------   ---------------------         
None.gif
                  -------------------
None.gif
                  month1  number(10,2)   --1月销售金额
None.gif
                  month2  number(10,2)   --2月销售金额
None.gif
                  month3  number(10,2)   --3月销售金额
None.gif
                  month4  number(10,2)   --4月销售金额
None.gif
                  month5  number(10,2)   --5月销售金额
None.gif
                  month6  number(10,2)   --6月销售金额
None.gif
                  month7  number(10,2)   --7月销售金额
None.gif
                  month8  number(10,2)   --8月销售金额
None.gif
                  month9  number(10,2)   --9月销售金额
None.gif
                  month10  number(10,2)     --10月销售金额
None.gif
                  month11  number(10,2)     --11月销售金额
None.gif
                  month12  number(10,2)     --12月销售金额
None.gif

None.gif                  结构转化的SQL语句为:
None.gif                  
create or replace view
None.gif                  v_sale(
year,month1,month2,month3,month4,month5,month6,month7,month8,month9,month10,month11,month12)
None.gif                  
as
None.gif                      
select 
None.gif                      substrb(
month,1,4),
None.gif                      
sum(decode(substrb(month,5,2),'01',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'02',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'03',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'04',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'05',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'06',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'07',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'08',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'09',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'10',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'11',sell,0)),
None.gif                      
sum(decode(substrb(month,5,2),'12',sell,0))
None.gif                      
from sale
None.gif                      
group by substrb(month,1,4);
None.gif
None.gif                  体会:要用decode 
/group by/ order by/sign/sum来实现不同报表的生成 
None.gif                  
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
None.gif                  CASE应用
None.gif
None.gif                  
1        1        部门a        800        男
None.gif                  
2        2        部门b        900        女
None.gif                  
3        3        部门a        400        男
None.gif                  
4        4        部门d        1400        女
None.gif                  
5        5        部门e        1200        男
None.gif                  
6        6        部门f        500        男
None.gif                  
7        7        部门a        300        女
None.gif                  
8        8        部门d        1000        男
None.gif                  
9        9        部门d        1230        女
None.gif                  
10        10        部门b        2000        女
None.gif                  
11        11        部门c        2000        男
None.gif                  
12        12        部门b        1200        男
None.gif
None.gif                    
SELECT jcxm as 部门,COUNT(seq) as 人数,
None.gif                      
SUM(CASE SEX WHEN 1 THEN 1 ELSE 0 ENDas 男,
None.gif                            
SUM(CASE SEX WHEN 2 THEN 1 ELSE 0 ENDas 女,
None.gif                      
SUM(CASE SIGN(zhi-800WHEN -1 THEN 1 ELSE 0 ENDas 
None.gif                  小于800元,
None.gif                      
SUM((CASE SIGN(zhi-800)*SIGN(zhi-1000)                    
ExpandedBlockStart.gifContractedBlock.gif                  
/**//*用*来实现<和>功能*/
None.gif                           
WHEN -1 THEN 1 ELSE 0 END)+(CASE zhi
None.gif                           
WHEN 800  THEN 1 ELSE 0 END)) as 从800至999,         
ExpandedBlockStart.gifContractedBlock.gif                  
/**//*注意别名不能以数字开头*/
None.gif                      
SUM((CASE SIGN(zhi-1000)*SIGN(zhi-1200)
None.gif                           
WHEN -1 THEN 1 ELSE 0 END)+(CASE zhi
None.gif                           
WHEN 1000 THEN 1 ELSE 0 END)) as 从1000元至1199元,
None.gif                      
SUM((CASE SIGN(zhi-1200WHEN 1 THEN 1 ELSE 0 END)
None.gif                      
+(CASE zhi WHEN 1200 THEN 1 ELSE 0 END)) as 大于1200元
None.gif                  
FroM ttt 
None.gif                  
GROUP BY jcxm
None.gif
None.gif                  部门名 人数    男       女   小于800元 从800至999 从1000元至1199元   大于1200元
None.gif                  部门a        
3        2        1        2        1           0   
None.gif                                             
0
None.gif                  部门b        
3        1        2        0        1           0   
None.gif                                             
2
None.gif                  部门c        
1        1        0        0        0           0   
None.gif                                            
1
None.gif                  部门d        
3        1        2        0        0           1   
None.gif                                            
2
None.gif                  部门e        
1        1        0        0        0             0 
None.gif                                              
1
None.gif                  部门f        
1        1        0        1        0           0   
None.gif                                            
0
None.gif
None.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值