zoukankan      html  css  js  c++  java
  • 笔记: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
    




  • 相关阅读:
    hive分区学习
    pyspark的学习
    往hive表中插入数据以及导出数据
    【Pytest学习3】setup和teardown简单用法,fixture里面的scope等于setup,用yield等于teardown
    【Pytest学习2】 pytest用例设计规则,terminal中使用常见命令行参数,pycharm中使用常见的命令行参数
    Jmeter响应内容显示乱码问题的解决办法
    Jmeter(三)测试计划和线程组
    Jmeter(二)Jmeter目录介绍 & 元件介绍
    JMeter之Ramp-up Period(in seconds)说明
    badboy云盘下载链接
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276069.html
Copyright © 2011-2022 走看看