笔记:Oracle SQL 高级查询简介 (3) MODEL子句,PIVOT与UNPIVOT子句

一、MODEL 子句

1、实例

model 子句可进行行间计算。

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold['01','2008'] = amount_sold['01','1998'],
    amount_sold['03','2008'] = amount_sold['01','1998'] + amount_sold['03','1998'],
    amount_sold['04','2008'] = amount_sold['04','1998'] *2
  )
order by prod_id, year, month_id;  

 


结果:

 

   	PROD_ID	YEAR	MONTH_ID	AMOUNT_SOLD
1	13	1998	01	1232.16
2	13	1998	03	1232.99
3	13	2008	01	1232.16
4	13	2008	03	2465.15
5	13	2008	04	
6	14	1998	04	1159.99
7	14	2008	01	
8	14	2008	03	
9	14	2008	04	2319.98


 

2、位置标记和符号标记访问数据单元

在以上的SQL中保留位置和符号标记

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[month_id='01',year='2008'] = amount_sold[month_id='01',year='1998'],
    amount_sold[month_id='03',year='2008'] = amount_sold[month_id='01',year='1998'] + amount_sold[month_id='03',year='1998'],
    amount_sold[month_id='04',year='2008'] = amount_sold[month_id='04',year='1998'] *2
  )
order by prod_id, year, month_id;  


结果与实例中一样

 


3、between and

用在measure中的聚合计算中。

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[month_id='01',year='2008'] = 
       avg(amount_sold)[month_id between 1 and 3,'1998']
  )
order by prod_id, year, month_id;  


 

4、any、is any

any 与位置标记合用,is any 与符号标记合用。

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold['01','2008'] = 
       avg(amount_sold)[any,year is any]
  )
order by prod_id, year, month_id;  


结果: 

 

 

   	PROD_ID	YEAR	MONTH_ID	AMOUNT_SOLD
1	13	1998	01	1232.16
2	13	1998	03	1232.99
3	13	2008	01	1232.575
4	14	1998	04	1159.99
5	14	2008	01	1159.99


 

5、currentv() 获取某个维度的当前值

譬如,将2008年第一个月设为1998年同月销售的2倍:

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold['01','2008'] = amount_sold[currentv(),'1998']
  )
order by prod_id, year, month_id;  


结果:

 

 

   	PROD_ID	YEAR	MONTH_ID	AMOUNT_SOLD
1	13	1998	01	1232.16
2	13	1998	03	1232.99
3	13	2008	01	1232.16
4	14	1998	04	1159.99
5	14	2008	01	


 

6、for 循环

语法如下:for month_id from 1 to 3 increment 1

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[for month_id from 1 to 3 increment 1,'2008'] 
    = amount_sold[currentv(),'1998']
  )
order by prod_id, year, month_id;  

 

 

7、处理空值、缺失值

用 is present, 与case when 连用:

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[for month_id from 1 to 3 increment 1,'2008'] 
    = case when amount_sold[currentv(),'1998'] is present then
        amount_sold[currentv(),'1998']*2
      else 
        0
      end    
  )
order by prod_id, year, month_id;


用presentv,相当于is present + case when

 

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[for month_id from 1 to 3 increment 1,'2008'] 
    =  presentv( amount_sold[currentv(),'1998'], amount_sold[currentv(),'1998']*2, 0 )
         
  )
order by prod_id, year, month_id; 


 用presentnnv, 存在且不为空。

 

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[for month_id from 1 to 3 increment 1,'2008'] 
    =  presentnnv( amount_sold[currentv(),'1998'], amount_sold[currentv(),'1998']*2, 0 )
         
  )
order by prod_id, year, month_id; 

 


用ignore nav (忽略空) 、 keep nav (保留空)

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model ignore nav
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)(
    amount_sold[for month_id from 1 to 3 increment 1,'2008'] 
       =   amount_sold[currentv(),'1998']*2 
         
  )
order by prod_id, year, month_id;  


8、更新已有单元

在前面的例子中,单元不存在则创建,存在更新 

使用 result update,指定只更新不创建

 

select prod_id, year, month_id, amount_sold  
from all_sales s where prod_id in (13,14) and s.cust_id = 987
model  
  partition by (prod_id)
  dimension by (month_id, year)
  measures (   amount_sold)
  rules update (
    amount_sold[for month_id from 1 to 3 increment 1,'2008'] 
       =   amount_sold[currentv(),'1998']*2 
         
  )
order by prod_id, year, month_id;  


 

二、PIVOT与UNPIVOT子句

1、PIVOT 行转列

 

select *
from (
  select s.month_id , s.prod_id, s.amount_sold 
  from all_sales s where s.year=1998 and s.prod_id in (13,14,15)
)
pivot (
  sum(amount_sold) for month_id in ('01' as JAN, '02' as FEB, '03' as MAR)
)
order by prod_id;

结果:

 

 

   	PROD_ID	JAN	FEB	MAR
1	13	125575.64	122325.21	61649.5
2	14	239773.24	278879.97	221083.56
3	15	165643.35	160732.4	22307.78


 

2、PIVOT  FOR 转换多列

 

select *
from (
  select s.month_id , s.prod_id, s.amount_sold 
  from all_sales s where s.year=1998 and s.prod_id in (13,14,15)
)
pivot (
  sum(amount_sold) for (month_id,prod_id) in 
  (('01',13) as JAN_13, 
  ('02',13) as FEB_13, 
  ('03',13) as MAR_13,
  ('01',14) as JAN_14, 
  ('02',14) as FEB_14, 
  ('03',14) as MAR_14)
)
 

结果:

 

 

   	JAN_13	        FEB_13	        MAR_13	  JAN_14	        FEB_14	        MAR_14
1	125575.64	122325.21	61649.5	  239773.24	        278879.97	221083.56



 

3、转换中使用多个聚合函数

 

select *
from (
  select s.month_id , s.prod_id, s.amount_sold 
  from all_sales s where s.year=1998 and s.prod_id in (13,14,15)
)
pivot (
  sum(amount_sold) as totl_amt,
  avg(amount_sold) as avg_amt
  for (month_id,prod_id) in 
  (('01',13) as JAN_13, 
  ('02',13) as FEB_13, 
  ('03',13) as MAR_13,
  ('01',14) as JAN_14, 
  ('02',14) as FEB_14, 
  ('03',14) as MAR_14)
)


结果:

 

 

   	JAN_13_TOTL_AMT	JAN_13_AVG_AMT	FEB_13_TOTL_AMT	FEB_13_AVG_AMT	MAR_13_TOTL_AMT	MAR_13_AVG_AMT	JAN_14_TOTL_AMT	JAN_14_AVG_AMT	FEB_14_TOTL_AMT	FEB_14_AVG_AMT	MAR_14_TOTL_AMT	MAR_14_AVG_AMT
1	125575.64	1231.1337254902	122325.21	1235.60818181818	61649.5	1232.99	239773.24	1217.12304568528	278879.97	1212.52160869565	221083.56	1214.74483516483


 

4、UNPIVOT 列转行

建立一个行转列的表

 

drop table pivot_sales_data;
create table pivot_sales_data as select *
from (
  select s.month_id , s.prod_id, s.amount_sold 
  from all_sales s where s.year=1998 and s.prod_id in (13,14,15)
)
pivot (
  sum(amount_sold)  
  for (month_id) in 
  (('01') as JAN, 
  ('02') as FEB, 
  ('03') as MAR)
)

结果:

 

 

   	PROD_ID	JAN	        FEB	        MAR
1	13	125575.64	122325.21	61649.5
2	14	239773.24	278879.97	221083.56
3	15	165643.35	160732.4	22307.78

列转回行:

 

 

select  * from pivot_sales_data
unpivot(
   amount_sold   for (month_id) in
  (JAN ,FEB, MAR )
)
 
结果:

 

 

   	PROD_ID	MONTH_ID	AMOUNT_SOLD
1	13	JAN	125575.64
2	13	FEB	122325.21
3	13	MAR	61649.5
4	14	JAN	239773.24
5	14	FEB	278879.97
6	14	MAR	221083.56
7	15	JAN	165643.35
8	15	FEB	160732.4
9	15	MAR	22307.78



 


 

posted @ 2015-10-03 23:37  lihui1625  阅读(294)  评论(0编辑  收藏  举报