oracle数据库的model,Oracle 11g学习笔记–model子句
Oracle 11g學習筆記–model子句
oracle 10g中新增的model子句可以用來進行行間計算。model子句允許像訪問數組中元素那樣訪問記錄中的某個列,這就提供了諸如電子表格計算之類的計算能力;
先來看一個簡單的例子:
select
prd_type_id, year, month, sales_amount
from all_sales
where prd_type_id between 1 and 2 and emp_id = 21
model
partition by (prd_type_id)
dimension by (month, year)
measures (amount sales_amount) (
sales_amount[1, 2004] = sales_amount[1, 2003],
sales_amount[2, 2004] = sales_amount[2, 2003] + sales_amount[3, 2003],
sales_amount[3, 2004] = round(sales_amount[3, 2003] * 1.25, 2)
)
order by prd_type_id, year, month;
partition by(prd_type_id)指定結果是根據prd_type_id分區的,所謂的分區就是在prd_type_id不等的情況下,一下的定義數組是互相不能訪問的;
dimension by(month, year) 定義數組的維數是month, year,這就意味著必須提供月份和年份才能訪問數組中的單元;
measures(amount sales_amount)表明數組中的每個單元包含一個數量,同時表明數組名為sales_amount.為了訪問sales_amount數組中標示2003年1月的那個單元,可以使用sales_amount[1, 2003],返回指定年月的銷量。
執行結果:
圖中的所有2004年的數據就是通過model生成出來的;
補充:對于數組的訪問方式,還可以顯示的訪問,如sales_amount[1, 2003]可以顯示指定維度sales_amount[month = 1, year = 2003],但是這種方式明顯更復雜。必須提一下的是兩者的區別:他們處理維度中空值得方式是不同的,例如sales_amount[null, 2003]返回月份為空值,年份為2003的銷量,而sales_amount[month = null, year = 2003]則不會返回任何有效數據,因為null=null的返回值總是false;
對于數組角標的維度還可以通過以下擴展方法:
1.between 和 and :
--將2004年1月的銷量設置為2003年1月至3月的銷量的平均值取整;
sales_amount[1, 2004] = round(sum(sales_amount)[month between 1 and 3, 2003], 2);
2.any 和 isany
--表示將2004年1月的銷量設置為所有年份月份的銷量值和取整
sales_amount[1, 2004] = round(sum(sales_amount)[any, year is any], 2);
3.currentv()
該函數用于獲的某個維度的當前值。
--表示將2004年第一個月的銷量設置為2003年同月銷量的1.25倍。注意此處用currentv()獲取當前月份,其值為1;sales_amount [1, 2004] = round(sales_amount[currentv(), 2003] *1.25, 2)
4.for循環
該表達式將2004年前三個月的銷量設置為2003年相應月份銷量的1.25倍。其中increment 1表示了變量每次循環+1
sales_amount[for month from 1 to 3 increment 1, 2004] = round (sales_amount[currentv(), 2003] * 1.25, 2)
5.處理空值和缺失值
■使用is present
當數據單元指定的單位在model子句執行之前存在,則is precent返回ture.
sales_amount[for month from 1 to 3 increment 1, 2004] =
case when sales_amount[currentv(), 2003] is present
then
round (sales_amount[currentv(), 2003] * 1.25, 2)
else
0
end
■presentv()
如果cell引用的記錄在model子句執行之前就存在,那么presentv(cell, expr1, expr2)返回表達式expr1。如果這條記錄不存在,則返回表達式expr2。
sales_amount[for month from 1 to 3 increment 1, 2004] = presentv(sales_amount[currentv(), 2003],
round(sales_amount[currentv(), 2003] * 1.25, 2), 0)
■presentnnv
presentnnv(cell, expr1, expr2)如果cell引用的單元在model子句執行之前已經存在,并且該單元的值不為空,則返回表達式expr1。如果記錄不存在,或單元值為空,則返回表達式expr2;
sales_amount[for month from 1 to 3 increment 1, 2004] = presentnnv(sales_amount[currentv(), 2003],
round(sales_amount[currentv(), 2003] * 1.25, 2), 0)
■ignore nav 和 keep nav
此關鍵詞使用在 model后面;
ignore nav返回值如下:
●空值或缺失數字值時返回0
●空值或缺失字符串值時返回空值字符串
●空值或缺失日期值時返回01-jan-2000。
●其它所有數據庫類型時返回空值
keep nav對空值或缺失數字值返回空值,默認條件;
select .....
from table
model ignore nav
paratition by ....
dimension by ....
measures .......
更新已有的單元
默認情況下,如果表達式左端的引用單元存在,則更新該單元。如果該單元不存在,就在數組中創建一條新的記錄。可以用rules update 改變這種默認行為,支出在單元不存在的情況下不創建新紀錄;
為了驗證效果,我們引用本文開頭的代碼:
select
prd_type_id, year, month, sales_amount
from all_sales
where prd_type_id between 1 and 2 and emp_id = 21
model
partition by (prd_type_id)
dimension by (month, year)
measures (amount sales_amount)
rules update (
sales_amount[1, 2004] = sales_amount[1, 2003],
sales_amount[2, 2004] = sales_amount[2, 2003] + sales_amount[3, 2003],
sales_amount[3, 2004] = round(sales_amount[3, 2003] * 1.25, 2)
)
order by prd_type_id, year, month;
引用從圖中可以看出已經沒有2004年的數據了;
總結
以上是生活随笔為你收集整理的oracle数据库的model,Oracle 11g学习笔记–model子句的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle_base,Oracle--
- 下一篇: 顺周期行业是指什么 顺势能赚钱的行业