参见 《Oracle SQL高级编程》。
SH@ prod> col product format a30
SH@ prod> col country format a10
SH@ prod> col region format a10
SH@ prod> col year format 9999
SH@ prod> col week format 99
SH@ prod> col sale format 999999
SH@ prod> set linesize 180 pagesize 100
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules automatic order(
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)] )
11 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 1 8.88 58 67.03
Xtend Memory Australia 1998 2 14.758 29 35.268
Xtend Memory Australia 1998 3 20.656 29 35.388
Xtend Memory Australia 1998 4 8.86 29 17.694
Xtend Memory Australia 1998 5 14.82 30 35.76
Xtend Memory Australia 1998 6 8.942 59 52.902
Xtend Memory Australia 1998 9 2.939 59 61.719
Xtend Memory Australia 1998 10 .01 118 114.831
Xtend Memory Australia 1998 12 -14.9 60 44.7
Xtend Memory Australia 1998 14 11.756 59 70.536
Xtend Memory Australia 1998 15 5.878 59 52.902
Xtend Memory Australia 1998 17 11.756 59 70.536
Xtend Memory Australia 1998 18 8.817 118 114.621
Xtend Memory Australia 1998 19 2.919 59 53.082
Xtend Memory Australia 1998 21 2.98 60 62.58
Xtend Memory Australia 1998 23 -11.756 118 105.804
Xtend Memory Australia 1998 26 11.756 118 129.316
Xtend Memory Australia 1998 27 14.632 58 60.396
Xtend Memory Australia 1998 28 .202 58 43.29
Xtend Memory Australia 1998 29 -14.228 58 43.29
Xtend Memory Australia 1998 34 -2.886 115 112.554
Xtend Memory Australia 1998 35 -8.638 58 51.768
Xtend Memory Australia 1998 38 -11.464 116 104.376
Xtend Memory Australia 1998 39 -5.792 116 121.512
Xtend Memory Australia 1998 40 -11.544 58 51.768
Xtend Memory Australia 1998 41 -17.376 58 52.488
Xtend Memory Australia 1998 42 -5.832 116 127.384
在一个使用MODEL子句的SQL语句中,有3组列:分区列,维度列以及度量值列。
上一个例子中:
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)] )
这个子句表示规则。
这个是一个递推的规则:本周的库存量 = 上周的 – 卖掉的 + 新进的。
Cv函数表示规则表达示左侧中的索引的值。
有则修改,没有则插入。
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules automatic order(
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)] ,
11 sale[1997 , 1] = 0 ,
12 receipts[1997 , 1] = 0 )
13 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1997 1 0 0 0
Xtend Memory Australia 1998 1 8.88 58 67.03
Xtend Memory Australia 1998 2 14.758 29 35.268
Xtend Memory Australia 1998 3 20.656 29 35.388
Xtend Memory Australia 1998 4 8.86 29 17.694
Xtend Memory Australia 1998 5 14.82 30 35.76
Xtend Memory Australia 1998 6 8.942 59 52.902
Xtend Memory Australia 1998 9 2.939 59 61.719
Xtend Memory Australia 1998 10 .01 118 114.831
Xtend Memory Australia 1998 12 -14.9 60 44.7
修改了1998年的初始值,下面其它月份的值也受到了影响,因为是递推的。
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules automatic order(
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)] ,
11 sale[1998 , 1] = 0 ,
12 receipts[1998 , 1] = 0 )
13 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 1 0 0 0
Xtend Memory Australia 1998 2 5.878 29 35.268
Xtend Memory Australia 1998 3 11.776 29 35.388
Xtend Memory Australia 1998 4 -.02 29 17.694
Xtend Memory Australia 1998 5 5.94 30 35.76
Xtend Memory Australia 1998 6 .062 59 52.902
Xtend Memory Australia 1998 9 2.939 59 61.719
Xtend Memory Australia 1998 10 .01 118 114.831
Xtend Memory Australia 1998 12 -14.9 60 44.7
Xtend Memory Australia 1998 14 11.756 59 70.536
SH@ prod> select product , country , year , week , sale from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures ( sale )
7 rules( sale[year in(2000 , 2001) , week in (1 , 52 , 53 )] order by year , week
8 = sale[cv(year) , cv(week)] * 1.10 )
9 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK SALE
------------------------------ ---------- ----- ---- -------
Xtend Memory Australia 2000 1 51
Xtend Memory Australia 2000 52 74
Xtend Memory Australia 2001 1 101
Xtend Memory Australia 2001 52 25
因为是return updated rows所以只返回了四行,不存在的行并不会被插入。
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules automatic order(
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)] ,
11 sale[2002, for week from 1 to 53 increment 1 ] = 0 ,
12 receipts[2002 , for week from 1 to 53 increment 1] = 0 )
13 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 1 8.88 58 67.03
Xtend Memory Australia 1998 2 14.758 29 35.268
Xtend Memory Australia 1998 3 20.656 29 35.388
Xtend Memory Australia 1998 4 8.86 29 17.694
Xtend Memory Australia 1998 5 14.82 30 35.76
下面的语句与上数第二个是一样的,只是没有加RETURN UPDATED ROWS。会返回所有行。
SH@ prod> select product , country , year , week , sale from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model
4 partition by (product , country)
5 dimension by (year , week)
6 measures ( sale )
7 rules( sale[year in(2000 , 2001) , week in (1 , 52 , 53 )] order by year , week
8 = sale[cv(year) , cv(week)] * 1.10 )
9 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK SALE
------------------------------ ---------- ----- ---- -------
Xtend Memory Australia 1998 1 58
Xtend Memory Australia 1998 2 29
Xtend Memory Australia 1998 3 29
Xtend Memory Australia 1998 4 29
Xtend Memory Australia 1998 5 30
Xtend Memory Australia 1998 6 59
Xtend Memory Australia 1998 9 59
Xtend Memory Australia 1998 10 118
Xtend Memory Australia 1998 12 60
由于规则只更新了一行,所以一定只返回一行。
SH@ prod> select product , country , year , week , sale from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory'
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures ( sale )
7 rules( sale[2000,1] = 0 )
8 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK SALE
------------------------------ ---------- ----- ---- -------
Xtend Memory Australia 2000 1 0
下面的语句会报错,因既没有显式的指定求解顺序,又没有加Automatic Order,此时Oracle会使用Sequential Order这种顺序,并不适合这个规则。
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory' and week < 10
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules (
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)])
11 order by product , country , year , week ;
select product , country , year , week , inventory , sale , receipts from sales_fact
*
ERROR at line 1:
ORA-32637: Self cyclic rule in sequential order MODEL
添加了Sequential Order之后,与上面的错误是一样的
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory' and week < 10
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules sequential order (
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)])
11 order by product , country , year , week ;
select product , country , year , week , inventory , sale , receipts from sales_fact
*
ERROR at line 1:
ORA-32637: Self cyclic rule in sequential order MODEL
解决办法1,添另Automatic Order:
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory' and week < 10
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules automatic order (
8 inventory[year , week] = nvl(inventory[cv(year) , cv(week)-1] , 0 )
9 - sale[cv(year) , cv(week)]
10 + receipts[cv(year) , cv(week)])
11 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 1 8.88 58 67.03
Xtend Memory Australia 1998 2 14.758 29 35.268
Xtend Memory Australia 1998 3 20.656 29 35.388
Xtend Memory Australia 1998 4 8.86 29 17.694
Xtend Memory Australia 1998 5 14.82 30 35.76
Xtend Memory Australia 1998 6 8.942 59 52.902
Xtend Memory Australia 1998 9 2.939 59 61.719
Xtend Memory Australia 1999 1 2.676 54 56.196
Xtend Memory Australia 1999 3 4.73 95 99.33
Xtend Memory Australia 1999 4 4.73 41 40.5
Xtend Memory Australia 1999 5 10.064 80 85.344
Xtend Memory Australia 1999 6 6.014 41 36.45
Xtend Memory Australia 1999 8 -2.196 103 100.914
Xtend Memory Australia 1999 9 13.806 53 69.342
Xtend Memory Australia 2000 1 -11.675 47 35.025
Xtend Memory Australia 2000 3 11.602 93 105.012
Xtend Memory Australia 2000 4 6.948 47 41.886
Xtend Memory Australia 2000 5 16.288 47 56.04
Xtend Memory Australia 2000 7 0 71 70.8
Xtend Memory Australia 2000 8 2.327 47 48.867
Xtend Memory Australia 2001 1 4.634 92 96.894
Xtend Memory Australia 2001 2 21.182 118 134.928
Xtend Memory Australia 2001 3 35.354 47 61.412
Xtend Memory Australia 2001 4 24.294 257 245.64
Xtend Memory Australia 2001 5 26.76 93 95.906
Xtend Memory Australia 2001 6 24.516 22 20.196
Xtend Memory Australia 2001 7 17.52 70 62.964
Xtend Memory Australia 2001 8 19.646 46 48.186
Xtend Memory Australia 2001 9 21.984 93 95.008
解决办法2,具体指定顺序:
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory' and week < 10
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules (
8 inventory[year , week] order by year , week
9 = nvl(inventory[cv(year) , cv(week)-1] , 0 )
10 - sale[cv(year) , cv(week)]
11 + receipts[cv(year) , cv(week)])
12 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 1 8.88 58 67.03
Xtend Memory Australia 1998 2 14.758 29 35.268
Xtend Memory Australia 1998 3 20.656 29 35.388
Xtend Memory Australia 1998 4 8.86 29 17.694
Xtend Memory Australia 1998 5 14.82 30 35.76
Xtend Memory Australia 1998 6 8.942 59 52.902
Xtend Memory Australia 1998 9 2.939 59 61.719
Xtend Memory Australia 1999 1 2.676 54 56.196
Xtend Memory Australia 1999 3 4.73 95 99.33
Xtend Memory Australia 1999 4 4.73 41 40.5
Xtend Memory Australia 1999 5 10.064 80 85.344
Xtend Memory Australia 1999 6 6.014 41 36.45
Xtend Memory Australia 1999 8 -2.196 103 100.914
Xtend Memory Australia 1999 9 13.806 53 69.342
Xtend Memory Australia 2000 1 -11.675 47 35.025
Xtend Memory Australia 2000 3 11.602 93 105.012
Xtend Memory Australia 2000 4 6.948 47 41.886
Xtend Memory Australia 2000 5 16.288 47 56.04
Xtend Memory Australia 2000 7 0 71 70.8
Xtend Memory Australia 2000 8 2.327 47 48.867
Xtend Memory Australia 2001 1 4.634 92 96.894
Xtend Memory Australia 2001 2 21.182 118 134.928
Xtend Memory Australia 2001 3 35.354 47 61.412
Xtend Memory Australia 2001 4 24.294 257 245.64
Xtend Memory Australia 2001 5 26.76 93 95.906
Xtend Memory Australia 2001 6 24.516 22 20.196
Xtend Memory Australia 2001 7 17.52 70 62.964
Xtend Memory Australia 2001 8 19.646 46 48.186
Xtend Memory Australia 2001 9 21.984 93 95.008
按照逻辑来说,要先知道1才能知道2,但是下面不知道是怎么求的。
SH@ prod> select product , country , year , week , inventory , sale , receipts from sales_fact
2 where country in ('Australia') and product = 'Xtend Memory' and week < 10
3 model return updated rows
4 partition by (product , country)
5 dimension by (year , week)
6 measures (0 inventory , sale , receipts)
7 rules (
8 inventory[year , week] order by year , week desc
9 = nvl(inventory[cv(year) , cv(week)-1] , 0 )
10 - sale[cv(year) , cv(week)]
11 + receipts[cv(year) , cv(week)])
12 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 1 8.88 58 67.03
Xtend Memory Australia 1998 2 5.878 29 35.268
Xtend Memory Australia 1998 3 5.898 29 35.388
Xtend Memory Australia 1998 4 -11.796 29 17.694
Xtend Memory Australia 1998 5 5.96 30 35.76
Xtend Memory Australia 1998 6 -5.878 59 52.902
Xtend Memory Australia 1998 9 2.939 59 61.719
Xtend Memory Australia 1999 1 2.676 54 56.196
Xtend Memory Australia 1999 3 4.73 95 99.33
Xtend Memory Australia 1999 4 0 41 40.5
Xtend Memory Australia 1999 5 5.334 80 85.344
Xtend Memory Australia 1999 6 -4.05 41 36.45
Xtend Memory Australia 1999 8 -2.196 103 100.914
Xtend Memory Australia 1999 9 16.002 53 69.342
Xtend Memory Australia 2000 1 -11.675 47 35.025
Xtend Memory Australia 2000 3 11.602 93 105.012
Xtend Memory Australia 2000 4 -4.654 47 41.886
Xtend Memory Australia 2000 5 9.34 47 56.04
Xtend Memory Australia 2000 7 0 71 70.8
Xtend Memory Australia 2000 8 2.327 47 48.867
Xtend Memory Australia 2001 1 4.634 92 96.894
Xtend Memory Australia 2001 2 16.548 118 134.928
Xtend Memory Australia 2001 3 14.172 47 61.412
Xtend Memory Australia 2001 4 -11.06 257 245.64
Xtend Memory Australia 2001 5 2.466 93 95.906
Xtend Memory Australia 2001 6 -2.244 22 20.196
Xtend Memory Australia 2001 7 -6.996 70 62.964
Xtend Memory Australia 2001 8 2.126 46 48.186
Xtend Memory Australia 2001 9 2.338 93 95.008
29 rows selected.
下面的这条语句中,不同的顺序求解出来的东西是不一样的。因为两条规则有相关性。
顺序求解
SH@ prod> select * from (
2 select product , country , year , week , inventory , sale , receipts from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures (0 inventory , sale , receipts)
8 rules sequential order(
9 inventory[year , week] order by year , week
10 = nvl(inventory[cv(year) , cv(week)-1] , 0 )
11 - sale[cv(year) , cv(week)]
12 + receipts[cv(year) , cv(week)] ,
13 receipts [ year in(2000 , 2001) , week in (51 , 52 , 53)] order by year , week
14 = receipts[cv(year) , cv(week)]*10 )
15 order by product , country , year , week )
16 where week > 50 ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 51 .04 58 61.236
Xtend Memory Australia 1998 52 5.812 86 92.152
Xtend Memory Australia 1999 53 -2.705 27 24.345
Xtend Memory Australia 2000 52 -1.383 67 660.67
Xtend Memory Australia 2001 51 4.86 115 1102.8
Xtend Memory Australia 2001 52 14.116 23 323.96
6 rows selected.
让Oracle自己去判断顺序。
SH@ prod> select * from (
2 select product , country , year , week , inventory , sale , receipts from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures (0 inventory , sale , receipts)
8 rules automatic order(
9 inventory[year , week] order by year , week
10 = nvl(inventory[cv(year) , cv(week)-1] , 0 )
11 - sale[cv(year) , cv(week)]
12 + receipts[cv(year) , cv(week)] ,
13 receipts [ year in(2000 , 2001) , week in (51 , 52 , 53)] order by year , week
14 = receipts[cv(year) , cv(week)]*10 )
15 order by product , country , year , week )
16 where week > 50 ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS
------------------------------ ---------- ----- ---- ---------- ------- ----------
Xtend Memory Australia 1998 51 .04 58 61.236
Xtend Memory Australia 1998 52 5.812 86 92.152
Xtend Memory Australia 1999 53 -2.705 27 24.345
Xtend Memory Australia 2000 52 593.22 67 660.67
Xtend Memory Australia 2001 51 997.38 115 1102.8
Xtend Memory Australia 2001 52 1298.2 23 323.96
下面语句中的avg_inventory[year, ANY] = avg(inventory)[cv(year) , week ],用ANY是因为右侧的表达式对于所有的week都会返回相同的值,所以没必要重复计算,对于所有的week只需要计算一次就行了。Avg后面的[cv(year) , week ]表示聚合的范围是这一年和所有周。
SH@ prod> select product , country , year , week , inventory ,avg_inventory , max_sale
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures (0 inventory , 0 avg_inventory , 0 max_sale , sale , receipts )
8 rules automatic order(
9 inventory[year , week] order by year , week
10 = nvl(inventory[cv(year) , cv(week)-1] , 0 )
11 - sale[cv(year) , cv(week)]
12 + receipts[cv(year) , cv(week)] ,
13 avg_inventory[year, ANY] = avg(inventory)[cv(year) , week ] , 表示聚合范围为这一年的所有周,因为这
14 max_sale[year , ANY] = max(sale)[cv(year),week]
15 )
16 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK INVENTORY AVG_INVENTORY MAX_SALE
------------------------------ ---------- ----- ---- ---------- ------------- ----------
Xtend Memory Australia 1998 1 8.88 -.72541667 172.56
Xtend Memory Australia 1998 2 14.758 -.72541667 172.56
Xtend Memory Australia 1998 3 20.656 -.72541667 172.56
Xtend Memory Australia 1998 4 8.86 -.72541667 172.56
Xtend Memory Australia 1998 5 14.82 -.72541667 172.56
Xtend Memory Australia 1998 6 8.942 -.72541667 172.56
Xtend Memory Australia 1998 9 2.939 -.72541667 172.56
Xtend Memory Australia 1998 10 .01 -.72541667 172.56
Xtend Memory Australia 1998 12 -14.9 -.72541667 172.56
Xtend Memory Australia 1998 14 11.756 -.72541667 172.56
Xtend Memory Australia 1998 15 5.878 -.72541667 172.56
Xtend Memory Australia 1998 17 11.756 -.72541667 172.56
Xtend Memory Australia 1998 18 8.817 -.72541667 172.56
Xtend Memory Australia 1998 19 2.919 -.72541667 172.56
Xtend Memory Australia 1998 21 2.98 -.72541667 172.56
以下的语句中规则会迭代5次,ITERATION_NUMBER从0到4。
SH@ prod> select year , week , sale , sale_list
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures ( cast(' ' as varchar2(50) ) sale_list , sale )
8 rules iterate (5) (
9 sale_list[year , week ] order by year , week =
10 sale[cv(year) , cv(week) - ITERATION_NUMBER + 2] ||
11 case when ITERATION_NUMBER = 0 then ' ' else ' , ' end ||
12 sale_list[cv(year) , cv(week)]
13 )
14 order by year , week ;
YEAR WEEK SALE SALE_LIST
----- ---- ------- --------------------------------------------------
1998 1 58 , , 58.15 , 29.39 , 29.49
1998 2 29 , 58.15 , 29.39 , 29.49 , 29.49
1998 3 29 58.15 , 29.39 , 29.49 , 29.49 , 29.8
1998 4 29 29.39 , 29.49 , 29.49 , 29.8 , 58.78
1998 5 30 29.49 , 29.49 , 29.8 , 58.78 ,
1998 6 59 29.49 , 29.8 , 58.78 , ,
1998 9 59 , , 58.78 , 117.76 ,
1998 10 118 , 58.78 , 117.76 , , 59.6
1998 12 60 117.76 , , 59.6 , , 58.78
1998 14 59 59.6 , , 58.78 , 58.78 ,
1998 15 59 , 58.78 , 58.78 , , 58.78
1998 17 59 58.78 , , 58.78 , 117.56 , 58.98
1998 18 118 , 58.78 , 117.56 , 58.98 ,
1998 19 59 58.78 , 117.56 , 58.98 , , 59.6
1998 21 60 58.98 , , 59.6 , , 117.56
1998 23 118 59.6 , , 117.56 , ,
1998 26 118 , , 117.56 , 57.52 , 57.72
上个例子的结果中有这样的数据
58 , , 58.15 , 29.39 , 29.49
是因为访问了不存在的行,返回空值造成的。
用PRESENTV解决这个问题。
PRESENTV(t , v1 , v2) 如果单元格t存在,返回v1,如果不存在,返回v2。
SH@ prod> select year , week , sale , sale_list
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures ( cast(' ' as varchar2(50) ) sale_list , sale )
8 rules iterate (5) (
9 sale_list[year , week ] order by year , week =
10 presentv(sale[cv(year) , cv(week) - ITERATION_NUMBER + 2] ,
11 sale[cv(year) , cv(week) - ITERATION_NUMBER + 2] ||
12 case when ITERATION_NUMBER = 0 then ' ' else ' , ' end ||
13 sale_list[cv(year) , cv(week)] ,
14 sale_list[cv(year) , cv(week)]
15 )
16 )
17 order by year , week ;
YEAR WEEK SALE SALE_LIST
----- ---- ------- --------------------------------------------------
1998 1 58 58.15 , 29.39 , 29.49
1998 2 29 58.15 , 29.39 , 29.49 , 29.49
1998 3 29 58.15 , 29.39 , 29.49 , 29.49 , 29.8
1998 4 29 29.39 , 29.49 , 29.49 , 29.8 , 58.78
1998 5 30 29.49 , 29.49 , 29.8 , 58.78 ,
1998 6 59 29.49 , 29.8 , 58.78 ,
1998 9 59 58.78 , 117.76 ,
1998 10 118 58.78 , 117.76 , 59.6
1998 12 60 117.76 , 59.6 , 58.78
1998 14 59 59.6 , 58.78 , 58.78 ,
1998 15 59 58.78 , 58.78 , 58.78
1998 17 59 58.78 , 58.78 , 117.56 , 58.98
1998 18 118 58.78 , 117.56 , 58.98 ,
1998 19 59 58.78 , 117.56 , 58.98 , 59.6
1998 21 60 58.98 , 59.6 , 117.56
1998 23 118 59.6 , 117.56 ,
1998 26 118 117.56 , 57.52 , 57.72
1998 27 58 117.56 , 57.52 , 57.72 , 57.72
1998 28 58 117.56 , 57.52 , 57.72 , 57.72 ,
1998 29 58 57.52 , 57.72 , 57.72 ,
1998 34 115 115.44 , 57.52 ,
1998 35 58 115.44 , 57.52 ,
1998 38 116 115.84 , 115.84 , 57.52
1998 39 116 115.84 , 115.84 , 57.52 , 58.32
用法同PRESENTV,只是多了非空条件。
PRESENTNNV(t , v1 , v2) 如果单元格t存在且非空,返回v1,否则,返回v2。
用REFERENCE关键字可以指定一个参考表。参考表可以查询自其它的表。
SH@ prod> select year , week , sale , prod_list_price
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 REFERENCE ref_prod on 引用如下的参考表
6 ( select prod_name , max(prod_list_price) prod_list_price from products
7 group by prod_name )
8 dimension by (prod_name ) 指定维度(自变量)
9 measures(prod_list_price) 指定度得值(因变量)
10 MAIN main_section
11 partition by (product , country) 分区可以说是维度的维度
12 dimension by (year , week)
13 measures ( sale , receipts , 0 prod_list_price )
14 rules (
15 prod_list_price[year , week ] order by year , week
16 = ref_prod.prod_list_price[cv(product)] 参考表中给定一个维度值,会给出一个measure值。
17 )
18 order by year , week ;
YEAR WEEK SALE PROD_LIST_PRICE
----- ---- ------- ---------------
1998 1 58 20.99
1998 2 29 20.99
1998 3 29 20.99
1998 4 29 20.99
1998 5 30 20.99
1998 6 59 20.99
1998 9 59 20.99
1998 10 118 20.99
1998 12 60 20.99
1998 14 59 20.99
1998 15 59 20.99
1998 17 59 20.99
1998 18 118 20.99
1998 19 59 20.99
1998 21 60 20.99
1998 23 118 20.99
1998 26 118 20.99
1998 27 58 20.99
1998 28 58 20.99
1998 29 58 20.99
1998 34 115 20.99
1998 35 58 20.99
1998 38 116 20.99
1998 39 116 20.99
1998 40 58 20.99
1998 41 58 20.99
1998 42 116 20.99
1998 43 58 20.99
1998 44 58 20.99
1998 45 58 20.99
1998 46 58 20.99
1998 47 58 20.99
SH@ prod> select year , week , sale , prod_list_price , iso_code
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 REFERENCE ref_prod on
6 ( select prod_name , max(prod_list_price) prod_list_price from products
7 group by prod_name )
8 dimension by (prod_name )
9 measures(prod_list_price)
10 REFERENCE ref_country on
11 ( select country_name , country_iso_code from countries )
12 dimension by (country_name )
13 measures (country_iso_code)
14 MAIN main_section
15 partition by (product , country)
16 dimension by (year , week)
17 measures ( sale , receipts , 0 prod_list_price , cast(' ' as varchar2(5)) iso_code ) 0表示度量值的默认值。
18 rules (
19 prod_list_price[year , week ] order by year , week
20 = ref_prod.prod_list_price[cv(product)] ,
21 iso_code[year , week] order by year , week
22 = ref_country.country_iso_code [cv(country)]
23 )
24 order by year , week ;
YEAR WEEK SALE PROD_LIST_PRICE ISO_C
---------- ---------- ---------- --------------- -----
1998 1 58.15 20.99 AU
1998 2 29.39 20.99 AU
1998 3 29.49 20.99 AU
1998 4 29.49 20.99 AU
1998 5 29.8 20.99 AU
1998 6 58.78 20.99 AU
1998 9 58.78 20.99 AU
1998 10 117.76 20.99 AU
1998 12 59.6 20.99 AU
1998 14 58.78 20.99 AU
1998 15 58.78 20.99 AU
1998 17 58.78 20.99 AU
1998 18 117.56 20.99 AU
1998 19 58.98 20.99 AU
1998 21 59.6 20.99 AU
1998 23 117.56 20.99 AU
1998 26 117.56 20.99 AU
1998 27 57.52 20.99 AU
1998 28 57.72 20.99 AU
1998 29 57.72 20.99 AU
1998 34 115.44 20.99 AU
1998 35 57.52 20.99 AU
1998 38 115.84 20.99 AU
1998 39 115.84 20.99 AU
1998 40 57.52 20.99 AU
1998 41 58.32 20.99 AU
1998 42 115.84 20.99 AU
默认的情况下(KEEP NAV)
SH@ prod> select product , country , year , week , sale
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures(sale)
8 rules sequential order (
9 sale[2001 , 1] order by year , week = sale[2001 , 1] ,
10 sale[2002 , 1] order by year , week = sale[2001 , 1] + sale[2002 , 1]
11 )
12 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK SALE
------------------------------ ---------- ----- ---- -------
Xtend Memory Australia 2001 1 92
Xtend Memory Australia 2002 1
指定KEEP NAV (NOT AVAILABLE VALUE),访问不存在的单元格时认为其是不确定值NULL。
SH@ prod> select product , country , year , week , sale
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model KEEP NAV return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures(sale)
8 rules sequential order (
9 sale[2001 , 1] order by year , week = sale[2001 , 1] ,
10 sale[2002 , 1] order by year , week = sale[2001 , 1] + sale[2002 , 1]
11 )
12 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK SALE
------------------------------ ---------- ----- ---- -------
Xtend Memory Australia 2001 1 92
Xtend Memory Australia 2002 1
指定IGNORE NAV,访问不存在的单元格时相当于返回了0,而不是NULL(不确定值)。
SH@ prod> select product , country , year , week , sale
2 from sales_fact
3 where country in ('Australia') and product = 'Xtend Memory'
4 model IGNORE NAV return updated rows
5 partition by (product , country)
6 dimension by (year , week)
7 measures(sale)
8 rules sequential order (
9 sale[2001 , 1] order by year , week = sale[2001 , 1] ,
10 sale[2002 , 1] order by year , week = sale[2001 , 1] + sale[2002 , 1]
11 )
12 order by product , country , year , week ;
PRODUCT COUNTRY YEAR WEEK SALE
------------------------------ ---------- ----- ---- -------
Xtend Memory Australia 2001 1 92
Xtend Memory Australia 2002 1 92
与分析函数类似,这里只是多了一个SQL MODEL ACYCLIC(并不全都是这个)
SH@ prod> explain plan for
2 select product , country , year , week , sale , receipts
3 from sales_fact
4 where country in ('Australia') and product = 'Xtend Memory'
5 model IGNORE NAV return updated rows
6 partition by (product , country)
7 dimension by (year , week)
8 measures( 0 inventory , sale , receipts )
9 rules automatic order (
10 inventory[year , week] order by year , week =
11 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
12 - sale[cv(year) , cv(week)] +
13 + receipts[cv(year) , cv(week)]
14 )
15 order by product , country , year , week ;
Explained.
SH@ prod> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 612713790
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 9072 | 310 (1)| 00:00:04 |
| 1 | SORT ORDER BY | | 162 | 9072 | 310 (1)| 00:00:04 |
| 2 | SQL MODEL ACYCLIC | | 162 | 9072 | 310 (1)| 00:00:04 |
|* 3 | TABLE ACCESS FULL| SALES_FACT | 162 | 9072 | 309 (1)| 00:00:04 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
15 rows selected.
SQL MODEL ACYCLIC FAST(只访问指定的行时)
SH@ prod> explain plan for
2 select product , country , year , week , sale_first_week
3 from sales_fact
4 where country in ('Australia') and product = 'Xtend Memory'
5 model IGNORE NAV return updated rows
6 partition by (product , country)
7 dimension by (year , week)
8 measures( 0 sale_first_week , sale )
9 rules automatic order (
10 sale_first_week[2000 , 1] = 0.12*sale[2000 , 1]
11 )
12 order by product , country , year , week ;
Explained.
SH@ prod> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2162534578
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 8100 | 310 (1)| 00:00:04 |
| 1 | SORT ORDER BY | | 162 | 8100 | 310 (1)| 00:00:04 |
| 2 | SQL MODEL ACYCLIC FAST| | 162 | 8100 | 310 (1)| 00:00:04 |
|* 3 | TABLE ACCESS FULL | SALES_FACT | 162 | 8100 | 309 (1)| 00:00:04 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
15 rows selected.
SQL MODEL CYCLIC(没有指定顺序时)
SH@ prod> explain plan for
2 select product , country , year , week , sale , receipts
3 from sales_fact
4 where country in ('Australia') and product = 'Xtend Memory'
5 model return updated rows
6 partition by (product , country)
7 dimension by (year , week)
8 measures( 0 inventory , sale , receipts )
9 rules automatic order (
10 inventory[year , week] =
11 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
12 - sale[cv(year) , cv(week)] +
13 + receipts[cv(year) , cv(week)]
14 )
15 order by product , country , year , week ;
Explained.
SH@ prod> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1486878524
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 9072 | 310 (1)| 00:00:04 |
| 1 | SORT ORDER BY | | 162 | 9072 | 310 (1)| 00:00:04 |
| 2 | SQL MODEL CYCLIC | | 162 | 9072 | 310 (1)| 00:00:04 |
|* 3 | TABLE ACCESS FULL| SALES_FACT | 162 | 9072 | 309 (1)| 00:00:04 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
15 rows selected.
SQL MODEL ORDERED(SEQUENTIAL的情况下)
SH@ prod> explain plan for
2 select product , country , year , week , sale , receipts
3 from sales_fact
4 where country in ('Australia') and product = 'Xtend Memory'
5 model return updated rows
6 partition by (product , country)
7 dimension by (year , week)
8 measures( 0 inventory , sale , receipts )
9 rules sequential order (
10 inventory[year , week] order by year , week =
11 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
12 - sale[cv(year) , cv(week)] +
13 + receipts[cv(year) , cv(week)]
14 )
15 order by product , country , year , week ;
Explained.
SH@ prod> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3753083011
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 9072 | 310 (1)| 00:00:04 |
| 1 | SORT ORDER BY | | 162 | 9072 | 310 (1)| 00:00:04 |
| 2 | SQL MODEL ORDERED | | 162 | 9072 | 310 (1)| 00:00:04 |
|* 3 | TABLE ACCESS FULL| SALES_FACT | 162 | 9072 | 309 (1)| 00:00:04 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
15 rows selected.
下面的例子中,谓词是作用在视图外面的,但是却发生了谓词推进。
谓词推进行原则:分区列上的谓词可以安全的推进。因为数据不会跨分区引用。
SH@ prod> explain plan for
2 select * from (
3 select product , country , year , week , sale , receipts
4 from sales_fact
5 model return updated rows
6 partition by (product , country)
7 dimension by (year , week)
8 measures( 0 inventory , sale , receipts )
9 rules automatic order (
10 inventory[year , week] =
11 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
12 - sale[cv(year) , cv(week)] +
13 + receipts[cv(year) , cv(week)]
14 )
15 )
16 where country in ('Australia') and product = 'Xtend Memory'
17 order by product , country , year , week ;
Explained.
SH@ prod> SELECT * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1551402430
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 16362 | 310 (1)| 00:00:04 |
| 1 | SORT ORDER BY | | 162 | 16362 | 310 (1)| 00:00:04 |
| 2 | VIEW | | 162 | 16362 | 309 (1)| 00:00:04 |
| 3 | SQL MODEL CYCLIC | | 162 | 9072 | | |
|* 4 | TABLE ACCESS FULL| SALES_FACT | 162 | 9072 | 309 (1)| 00:00:04 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
16 rows selected.
下面的例子中Oracle自动对能推进的谓词和不能推进的谓词进行了拆分。
维度列上的谓词推进不安全,因为被排除的维度值可能被其它的维度值引用。
SH@ prod> explain plan for
2 select * from (
3 select product , country , year , week , sale , receipts
4 from sales_fact
5 model return updated rows
6 partition by (product , country)
7 dimension by (year , week)
8 measures( 0 inventory , sale , receipts )
9 rules automatic order (
10 inventory[year , week] =
11 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
12 - sale[cv(year) , cv(week)] +
13 + receipts[cv(year) , cv(week)]
14 )
15 )
16 where country in ('Australia') and product = 'Xtend Memory'
17 and year = 2000
18 order by product , country , year , week ;
Explained.
SH@ prod> SELECT * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1551402430
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 16362 | 310 (1)| 00:00:04 |
| 1 | SORT ORDER BY | | 162 | 16362 | 310 (1)| 00:00:04 |
|* 2 | VIEW | | 162 | 16362 | 309 (1)| 00:00:04 |
| 3 | SQL MODEL CYCLIC | | 162 | 9072 | | |
|* 4 | TABLE ACCESS FULL| SALES_FACT | 162 | 9072 | 309 (1)| 00:00:04 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("YEAR"=2000)
4 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
17 rows selected.
注意:这种物化视图不能设置成fast incremental refresh。
SH@ prod> create materialized view mv_model_inventory
2 enable query rewrite as
3 select product , country , year , week , sale , receipts
4 from sales_fact
5 where country in ('Australia') and product = 'Xtend Memory'
6 model return updated rows
7 partition by (product , country)
8 dimension by (year , week)
9 measures( 0 inventory , sale , receipts )
10 rules sequential order (
11 inventory[year , week] order by year , week =
12 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
13 - sale[cv(year) , cv(week)] +
14 + receipts[cv(year) , cv(week)]
15 );
Materialized view created.
SH@ prod>
SH@ prod> explain plan for
2 select * from (
3 select product , country , year , week , sale , receipts
4 from sales_fact
5 where country in ('Australia') and product = 'Xtend Memory'
6 model return updated rows
7 partition by (product , country)
8 dimension by (year , week)
9 measures( 0 inventory , sale , receipts )
10 rules sequential order (
11 inventory[year , week] order by year , week =
12 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
13 - sale[cv(year) , cv(week)] +
14 + receipts[cv(year) , cv(week)]
15 )
16 )
17 where country in ('Australia') and product = 'Xtend Memory'
18 order by product , country , year , week ;
Explained.
SH@ prod> SELECT * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2344724570
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 159 | 16059 | 4 (25)| 00:00:01 |
| 1 | SORT ORDER BY | | 159 | 16059 | 4 (25)| 00:00:01 |
|* 2 | MAT_VIEW REWRITE ACCESS FULL| MV_MODEL_INVENTORY | 159 | 16059 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("MV_MODEL_INVENTORY"."COUNTRY"='Australia' AND
"MV_MODEL_INVENTORY"."PRODUCT"='Xtend Memory')
Note
-----
- dynamic sampling used for this statement (level=2)
19 rows selected.
SH@ prod> explain plan for
2 select /*+ parallel(sf 4) */
3 product , country , year , week , sale , receipts
4 from sales_fact sf
5 where country in ('Australia') and product = 'Xtend Memory'
6 model return updated rows
7 partition by (product , country)
8 dimension by (year , week)
9 measures( 0 inventory , sale , receipts )
10 rules automatic order (
11 inventory[year , week] order by year , week =
12 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
13 - sale[cv(year) , cv(week)] +
14 + receipts[cv(year) , cv(week)]
15 );
Explained.
SH@ prod> SELECT * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2789944137
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 162 | 9072 | 86 (0)| 00:00:02 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 162 | 9072 | | | Q1,01 | P->S | QC (RAND) |
| 3 | BUFFER SORT | | 162 | 9072 | | | Q1,01 | PCWP | |
| 4 | SQL MODEL ACYCLIC | | 162 | 9072 | | | Q1,01 | PCWP | |
| 5 | PX RECEIVE | | 162 | 9072 | 86 (0)| 00:00:02 | Q1,01 | PCWP | |
| 6 | PX SEND HASH | :TQ10000 | 162 | 9072 | 86 (0)| 00:00:02 | Q1,00 | P->P | HASH |
| 7 | PX BLOCK ITERATOR | | 162 | 9072 | 86 (0)| 00:00:02 | Q1,00 | PCWC | |
|* 8 | TABLE ACCESS FULL| SALES_FACT | 162 | 9072 | 86 (0)| 00:00:02 | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
8 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')
20 rows selected.
如果Model子句中的分区列与表的分区键相匹配的话,那么就可以用到分区剪裁来优化。
SH@ prod> with t1 as
2 (
3 select product , country , year , week , inventory , sale , receipts
4 from sales_fact sf
5 where country in ('Australia') and product = 'Xtend Memory'
6 model return updated rows
7 partition by (product , country)
8 dimension by (year , week)
9 measures( 0 inventory , sale , receipts )
10 rules automatic order (
11 inventory[year , week] order by year , week =
12 nvl(inventory[cv(year) , cv(week) -1 ] , 0)
13 - sale[cv(year) , cv(week)] +
14 + receipts[cv(year) , cv(week)]
15 )
16 )
17 select product , country , year , week , inventory , sale , receipts , prev_sale
18 from t1
19 model return updated rows
20 partition by ( product , country )
21 dimension by ( year , week )
22 measures ( inventory , sale , receipts , 0 prev_sale )
23 rules sequential order (
24 prev_sale[year , week ] order by year , week =
25 nvl(sale[cv(year)-1 , cv(week)] , 0)
26 )
27 order by 1 , 2 , 3 , 4 ;
PRODUCT COUNTRY YEAR WEEK INVENTORY SALE RECEIPTS PREV_SALE
------------------------------ ---------- ----- ---- ---------- ------- ---------- ----------
Xtend Memory Australia 1998 1 8.88 58 67.03 0
Xtend Memory Australia 1998 2 14.758 29 35.268 0
Xtend Memory Australia 1998 3 20.656 29 35.388 0
Xtend Memory Australia 1998 4 8.86 29 17.694 0
Xtend Memory Australia 1998 5 14.82 30 35.76 0
Xtend Memory Australia 1998 6 8.942 59 52.902 0
Xtend Memory Australia 1998 9 2.939 59 61.719 0
Xtend Memory Australia 1998 10 .01 118 114.831 0
Xtend Memory Australia 1998 12 -14.9 60 44.7 0
Xtend Memory Australia 1998 14 11.756 59 70.536 0
Xtend Memory Australia 1998 15 5.878 59 52.902 0
Xtend Memory Australia 1998 17 11.756 59 70.536 0
Xtend Memory Australia 1998 18 8.817 118 114.621 0
Xtend Memory Australia 1998 19 2.919 59 53.082 0
Xtend Memory Australia 1998 21 2.98 60 62.58 0
Xtend Memory Australia 1998 23 -11.756 118 105.804 0
Xtend Memory Australia 1998 26 11.756 118 129.316 0
Xtend Memory Australia 1998 27 14.632 58 60.396 0
Xtend Memory Australia 1998 28 .202 58 43.29 0
Xtend Memory Australia 1998 29 -14.228 58 43.29 0
Xtend Memory Australia 1998 34 -2.886 115 112.554 0
Xtend Memory Australia 1998 35 -8.638 58 51.768 0
Xtend Memory Australia 1998 38 -11.464 116 104.376 0
Xtend Memory Australia 1998 39 -5.792 116 121.512 0
Xtend Memory Australia 1998 40 -11.544 58 51.768 0
Xtend Memory Australia 1998 41 -17.376 58 52.488 0
Xtend Memory Australia 1998 42 -5.832 116 127.384 0
Xtend Memory Australia 1998 43 -11.584 58 51.768 0
Xtend Memory Australia 1998 44 -8.708 58 60.396 0
Xtend Memory Australia 1998 45 -23.088 58 43.14 0
Xtend Memory Australia 1998 46 -20.212 58 60.396 0
Xtend Memory Australia 1998 47 -17.326 58 60.606 0
Xtend Memory Australia 1998 48 5.682 173 195.568 0
Xtend Memory Australia 1998 50 -2.876 29 25.884 0
Xtend Memory Australia 1998 51 .04 58 61.236 0
Xtend Memory Australia 1998 52 5.812 86 92.152 0
Xtend Memory Australia 1999 1 2.676 54 56.196 58.15
Xtend Memory Australia 1999 3 4.73 95 99.33 29.49
Xtend Memory Australia 1999 4 4.73 41 40.5 29.49
Xtend Memory Australia 1999 5 10.064 80 85.344 29.8
Xtend Memory Australia 1999 6 6.014 41 36.45 58.78
Xtend Memory Australia 1999 8 -2.196 103 100.914 0
Xtend Memory Australia 1999 9 13.806 53 69.342 58.78