oracle sql 高階程式設計學習筆記(二十一)
阿新 • • 發佈:2018-11-21
一、行求解順序
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;
對於列中求出每週的庫存,我們把 automatic order 註釋掉 ,
automatic order 允許資料庫自動識別規則之間的依賴關係
會啟用預設的排序sequential order 規則排序, 既rules中規則先後順序
sql語句會報如下錯誤
ORA-32637: 順序排序 MODEL 中的自迴圈規則
這是因為 程式碼inventory [ cv(year), cv(week) - 1 ]子句進行了跨行引用,庫存列的值必須按照周的升序來進行計算,
例如 第二週的庫存必須在得到第一週的庫存值後才能進行計算。
當然除了使用 automatic order 我們也可以直接在規則進行排序
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 ] order by year,week asc --通過order自己顯示聲明瞭行求解順序
= nvl(inventory [ cv(year), cv(week) - 1 ], 0) - sale [ cv(year), cv(week) ] + receipts [ cv(year), cv(week) ]
)
order by product, country, year, week;
二、規則求解順序
select * from (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 sequential order
(inventory [ year, week ] order by year,week asc
= nvl(inventory [ cv(year), cv(week) - 1 ], 0) - sale [ cv(year), cv(week) ] + receipts [ cv(year), cv(week) ]
,
receipts[year in(2000,2001),week in (51,52,53)]
order by year ,week asc -- 這裡排序不能少 不然因為上面規則中涉及到跨行處理 不然還是會報 ORA-32637錯誤
=receipts[cv(year),cv(week)]*10
)
order by product, country, year, week)
where week>50 --用於篩選修改的receipts,便於檢視結果;
從結果中明顯看到,先按照求解庫存後,再重新計算收入receipts
三、聚合函式
select product, country, year, week, inventory, sale, receipts, avg_inventory, max_sale
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,0 avg_inventory,0 max_sale, 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) ]
,
avg_inventory[year,any]=round(avg(inventory)[cv(year),week],2),
max_sale[year,any]=max(sale)[cv(year),week]
)
order by product, country, year, week
avg_inventory[year, ANY] = avg(inventory)[cv(year) , week ],用ANY是因為右側的表示式對於所有的week都會返回相同的值,所以沒必要重複計算,對於所有的week只需要計算一次就行了。Avg後面的[cv(year) , week ]表示聚合的範圍是這一年和所有周。
四、迭代
1、例項演示
select year, week, sale, sale_list
from sales_fact
where country = 'Australia'
and product = 'Xtend Memory'
model return updated rows
partition by(product, country)
dimension by(year, week)
measures( cast('' as varchar2(50))sale_list, sale )
rules iterate(5)-- 規則會迭代5次,ITERATION_NUMBER從0到4。
( sale_list[year,week] order by year,week asc=
sale[cv(year),cv(week)-iteration_number+2]||--cv(week)-iteration_number+2 來訪問前兩週和後兩週的資料
case when iteration_number=0 then '' else ',' end||
-- case語句在為每個列表中除了第一個成員外每個成員都加上逗號。
sale_list[cv(year),cv(week)]
)
order by year, week
同樣這也是列轉行 可以通過pivot函式實現
2、空值
語法
presentv(cell_reference,expr1,expr2)
表示 如果 cell_reference存在,則返回 expr1,不存在則返回expr2
PRESENTNNV(NOT NULL VALUE)
用法同PRESENTV,只是多了非空條件。
PRESENTNNV(t , v1 , v2) 如果單元格t存在且非空,返回v1,否則,返回v2。
接著示列中的例子
select year, week, sale, sale_list
from sales_fact
where country = 'Australia'
and product = 'Xtend Memory'
model return updated rows
partition by(product, country)
dimension by(year, week)
measures( cast('' as varchar2(50))sale_list, sale )
rules iterate(5)
( sale_list[year,week] order by year,week asc=
presentv(
sale[cv(year),cv(week)-iteration_number+2],
sale[cv(year),cv(week)-iteration_number+2]||
case when iteration_number=0 then '' else ',' end||
sale_list[cv(year),cv(week)],
sale_list[cv(year),cv(week)] )
)
order by year, week
結果解決了 示列中存在雙逗號問題。