1. 程式人生 > >oracle sql 高階程式設計學習筆記(二十)

oracle sql 高階程式設計學習筆記(二十)

一、Model 子句剖析:

通過 model return updated rows 或者model來宣告這個語句
使用model子句。一個model子句有三組列,分割槽列,唯獨列,
以及度量值列。
分割槽列類似於電子表格excel中的一張工作表,
維度列類似於行標籤(A,B,C……)和列標籤(1,2,3……)
度量值類似於 含有公式的單元格

例項演示:

實現求某地區某周的庫存

select product, country, year, week, inventory, sale, receipts
  from sales_fact
 where country = 'Australia'
and product = 'Xtend Memory' model return updated rows partition by(product, country) dimension by(year, week) measures(0 inventory, sale, receipts) rules automatic order(inventory [ year, week ] = nvl(inventory [ cv(year), cv(week) - 1 ], 0) - sale [ cv(year), cv(week) ] + receipts [ cv(year
), cv(week) ]) order by product, country, year, week;

查詢結果:
這裡寫圖片描述

通過上面例項演示:
實列中一個非常有用的函式cv。cv表示現值
可以用來表示從規則左側計算得來規則右側的列值。
例如:cv(year) 指的是規則左側year列的指。其實就是引用某個單元格的值。
假如資料來到 第一行 year=1998,week=1
inventory[cv(year),cv(week)-1]表示 取 year=1998,week=0 的庫存 很明顯是空
sale [ cv(year), cv(week) ] 表示 year=1998,week=1的銷售 sale 值
同理 receipts [ cv(year), cv(week) ] 表示 year=1998,week=1的 receipts 值

inventory [ 1998, 1 ] = nvl(inventory [ cv(year), cv(week) - 1 ], 0) - sale [ cv(year), cv(week) ] + receipts [ cv(year), cv(week) ]

inventory [ 1998, 1 ] = nvl(inventory [ cv(1998), cv(1) - 1 ], 0) - sale [ cv(1998), cv(1) ] + receipts [ cv(1998), cv(1) ])
= 0-58.15+67.03=8.88

二、符號標記

CV函式提供了引用一個單元格的能力,還能通過使用位置或符號標記來引用某個單獨的單元格或單元格組。此外還可以通過for迴圈來以類似陣列的方式建立或修改多個單元格。位置標記提供了在結果集中插入一個新單元格或更新一個單元格的能力:如果存在則更新,不存在則插入,這種概念稱為upsert特性是update和insert功能的融合版本

select product, country, year, week, inventory, sale, receipts
  from sales_fact
 where country = 'Australia'
   and product = 'Xtend Memory' 
   model return updated rows 
   partition by(product, country)
   dimension by(year, week)
   measures(0 inventory, sale, receipts) 
   rules automatic
   order(inventory [ year, week ] = nvl(inventory [ cv(year), cv(week) - 1 ], 0) - sale [ cv(year), cv(week) ] + receipts [ cv(year), cv(week) ]
   ,sale[2002,1]=0,
    receipts[2002,1]=0)
 order by product, country, year, week;

資料中沒有滿足年份是2002,week是1的資料,所以sale列以及receipts列資料都會插入進去,見結果集中最後一行資料
這裡寫圖片描述

三、符號標記

僅提供了update功能,而位置標記提供了upsert功能。注意 model子句中不能使用別名點,會如下錯誤:
這裡寫圖片描述

將year =2000以及2001 week in(1,52,53)的 sale改為原來的1.1倍

select country, product,year, week, sale
  from sales_fact  
 where country = 'Australia'
   and product = 'Xtend Memory' 
   model  return updated rows
--  return updated rows 只返回修改的記錄行
    partition by(country, product) 
    dimension by(year, week)
    measures(sale)
    rules(
              sale [ year in (2000, 2001),
              week in (1, 52, 53) ] order by year,
             week = sale [ cv(year),
             cv(week) ] * 1.10
             )
 order by year, week

這裡寫圖片描述

可見,對於不滿足week條件=53的記錄,既沒有修改也沒有插入,符號標記不具有insert功能。

四、for迴圈

select product, country, year, week, inventory, sale, receipts
  from sales_fact
 where country = 'Australia'
   and product = 'Xtend Memory' 
   model return updated rows 
   partition by(product, country)
   dimension by(year, week)
   measures(0 inventory, sale, receipts) 
   rules automatic
   order(inventory [ year, week ] = nvl(inventory [ cv(year), cv(week) - 1 ], 0) - sale [ cv(year), cv(week) ] + receipts [ cv(year), cv(week) ]
   ,sale[2002,for week from 1 to 53 increment 1]=0,
   receipts[2002,for week from 1 to 53 increment 1]=0
   )--increment 設定步長
 order by product, country, year, week;

結果如下,通過for迴圈初始化2002年的資料,可見for迴圈也支援upsert功能
這裡寫圖片描述