a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 416|回复: 1

[考试辅导] Oracle10g的MODELSQL进行行间计算

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
 以产品产量表为例,一个工厂(用code表示)生产多种产品(用p_id表示),每种产品具有生产量(v1)和销售量(v2)$ [; s& t- W* T- [
  产品代码具有审核关系,比如’10’=’30’+’31’,其中’10’代表大类,’30’和’31’代表’10’大类下的小类。
; n* E: U+ ~7 ], Y2 k6 w; G9 ^: [( y  SQL> create table t603 (code varchar(10),p_id varchar(7),v1 number(10),v2 number(10));
& W$ u( K2 K. h: B' g  Table created.
1 Z1 o; Z% f4 g1 v6 u  SQL> insert into t603 values(’600001’,’30’,1,1);6 T& g8 p- L, ^! L# C0 n6 S. h
  SQL> insert into t603 values(’600001’,’31’,1,1);
. U/ Y( ~3 ^: E& _! g# h  SQL> insert into t603 values(’600001’,’10’,2,2);) [) A( L4 {# T
  SQL> insert into t603 values(’600002’,’10’,3,2);
: d: L  X3 m! a, i; b  SQL> insert into t603 values(’600002’,’31’,2,1);
4 o, q7 _; A. R; A" _  N  SQL> insert into t603 values(’600002’,’30’,2,1);1 W$ U; A8 N; c' z1 v
  SQL> commit;
1 {" O9 L1 t: ?( r% w" m+ O& L: F  Commit complete.
$ u" x# w; B4 p0 i  SQL> select * from t603;, A# e  R. i) p/ f; M
  CODE P_ID V1 V27 I. _4 ?. Q- o7 Q, v  N
  600001 30 1 1
* W! d5 h' d; d8 g2 M  600001 31 1 11 O& |# i0 X  A4 x! |
  600001 10 2 26 M' i, W; d! I- _* t, C
  600002 10 3 25 q  U3 r0 `1 k4 x6 }
  600002 31 2 1
$ p  x! d( i1 s( X  600002 30 2 1, v$ v1 T! y9 h5 n: D
  6 rows selected.
2 Z; r+ L! I( V6 S4 P  SELECT code,
! p: A4 ?7 [& `6 E. {  p_id, v1
. c! N( r! h- q  FROM t603# F0 C' {+ O+ P9 L1 @
  WHERE code IN (’600001’,’600002’)% f4 `# J# O5 ~/ U7 l( P
  MODEL RETURN UPDATED ROWS, C( W5 h/ i- \/ s0 ~, b% M/ Y; S
  PARTITION BY (code)# y, h/ z; Y5 X5 |+ b6 q$ d- w
  DIMENSION BY (p_id)( I- }: z6 Y0 y6 _# }
  MEASURES (v1)* W# G' t2 a1 P9 p$ C( U2 @( g. R
  RULES (# K( c% w) g" F" q
  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’])
2 U" a) g3 J& s# @" K3 I: L  ORDER BY code, p_id;) P) q* s, B2 T6 K1 b( O2 t
  其中rule表示计算规则,’err1’表示这条审核关系的代号,它的值等于P_ID为’30’的v1值+P_ID为’31’的v1值-P_ID为’10’的v1值
& ~4 s2 n) j! Z7 C  PARTITION BY (code)表示按工厂分区,即审核在一个工厂内的产品
3 |4 w! H) z0 c) `2 e$ Y7 G# O+ p  MODEL 关键字后面的 RETURN UPDATED ROWS 子句将结果限制为在该查询中创建或更新的那些行。使用该子句是使结果集只包含新计算的值,在本例中就是审核结果5 K$ `2 n/ X* y( p5 \
  CODE P_ID V1. D1 A. s! ^. Y( T9 [+ c9 e
  600001 err1 0, E& |( M3 k2 F  l2 F0 {
  600002 err1 1
9 Z3 h5 ^2 N1 u* X  如果返回值=0,表示v1[’30’] + v1[’31’] =v1[’10’]审核通过,否则,审核不通过9 N8 z! q5 [0 O' ~
  SELECT code,0 C% C- R  A4 a7 M
  p_id, v1,v2" L  v7 ^, c8 S9 `, g+ {
  FROM t603- P7 G' T" H+ E) _; N+ {' D8 V
  WHERE code IN (’600001’,’600002’)
0 ]  N/ v% A! H% U) Q, A8 i1 W  MODEL RETURN UPDATED ROWS
2 C0 k# n# |1 ]- V. k2 m. {/ m0 r, F  PARTITION BY (code)4 A. H0 \3 v! ~. u. y  c/ B
  DIMENSION BY (p_id)
- [, P2 J4 K8 `5 ~2 F  MEASURES (v1,v2)% d% x' M2 X# n8 g# Y! G, F
  RULES (
& F5 D& e& N3 O0 u+ W' W  o; q  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’],( z6 `' f# L5 k
  v2[’err1’] = v2[’30’] + v2[’31’] -v2[’10’])
6 f" e6 K7 U: r! w# [  ORDER BY code, p_id;
2 |, _1 L+ z) c1 ]! o8 O  CODE P_ID V1 V2; I$ ?% x: F& N* H( L
  600001 err1 0 08 X7 @- E7 U  Y  D0 w2 B- q
  600002 err1 1 0; h4 C$ l1 _9 m
  如果表格中包含多个维度的数据,比如时间,多个维度都可以编写规则,比如2008年的审核关系8 H1 C# K9 z. ^) r
  SELECT year,code,
5 P$ o5 C3 c) ?7 }  p_id, v1
" F6 Z2 o. a% k8 Y  FROM t603_1
# N# h: z. k& y- C  WHERE code IN (’600001’,’600002’)
! r/ Y- y4 E" E: g) R  MODEL RETURN UPDATED ROWS
' b6 E: t) V+ v9 Z$ E$ u3 a  PARTITION BY (code)) k- U- E. O* V
  DIMENSION BY (p_id,year)5 y9 f! V1 f& \) E6 A. v
  MEASURES (v1)
/ I  D0 a' K8 l7 a: t3 V; U% V  RULES (
2 Z; ^1 \7 R( V; {* o' R4 i  a/ b  v1[’err1’,2008] = v1[’30’,2008] + v1[’31’,2008] -v1[’10’,2008])$ o( ]: z& W9 J9 {2 R
  ORDER BY code, p_id;- U$ A/ l8 O" O5 A
  YEAR CODE P_ID V1% e. e% [9 d, G' w; G2 E
  2008 600001 err1 0
% A3 o  I8 Z2 V2 X( A7 V% w  2008 600002 err1 1
3 ]6 s2 S0 R  A( P  如果维度不影响规则,也可以只分区,而沿用原来的规则
/ v  r; |9 \* z$ e! V6 b  SELECT year,code,
. @4 V& e; ]. T0 A  p_id, v1" Y! T8 o1 L$ c8 f# @" i
  FROM t603_1
" M. g# u- @- t3 M3 B  M  WHERE code IN (’600001’,’600002’)+ `9 C6 {0 y; o: {% F
  MODEL RETURN UPDATED ROWS! e: Q9 |' L) ?/ V3 B$ t
  PARTITION BY (code,year)* w. i2 ?7 t' ]& G0 [
  DIMENSION BY (p_id)5 L$ o" K3 k2 a
  MEASURES (v1)5 O2 K3 ~) m" P! r) ?: a
  RULES (
' Y0 i2 u' j0 T$ R* s7 }3 \; O. W  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’]), W) D9 G, M! D) M$ s# |! m8 V. q
  ORDER BY code, p_id;( v$ l% H  j% U8 h
  YEAR CODE P_ID V1
( F2 I/ Z4 {9 v  2008 600001 err1 0
- ~, B" B8 ^& t  2008 600002 err1 1) F3 `3 }$ m0 c0 J
  SQL> create table t603_2 as select * from t603_1;
. E: F3 J# {, L9 ~) Q  Table created.
  }# P& j9 e4 F% z8 m, i" ~( Y  SQL> insert into t603_2 select ’2007’ year,code,p_id,v1,v2 from t603_1;
9 I' C, I: f9 B4 c' b8 p  6 rows created.
回复

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:20 | 显示全部楼层

Oracle10g的MODELSQL进行行间计算

 如果表中具有多个年份的数据,每个年份的审核结果都能显示+ a$ l5 D2 A- g- T, D0 Y
  SELECT year,code,' K( Y1 J. ]+ ~; Y
  p_id, v1
8 S2 b' w6 w( x2 A/ J/ F  FROM t603_2+ X6 D9 e. S. P! s  `8 Y8 }, G
  WHERE code IN (’600001’,’600002’)1 K& D8 J1 G5 r5 f1 Z" ~+ C7 M& D
  MODEL RETURN UPDATED ROWS- V/ r; }% _6 K+ r4 d4 w
  PARTITION BY (code,year)
1 h1 t' W* m# P- X4 H* i9 b  DIMENSION BY (p_id)( f! f! s, }, \" `- V# s6 }
  MEASURES (v1)
9 ^$ X  B; u" r& q+ I  RULES (
, t5 S8 u$ Z) ^) l+ `8 V  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’])1 Q% p: c4 b/ s% C& U/ ~
  ORDER BY code, p_id;( e# R' j- ]. x; f6 [
  YEAR CODE P_ID V1" C1 Y: W2 E6 ?) S: a7 v
  2008 600001 err1 0) G1 v8 k# w: ^) e5 B, i
  2007 600001 err1 0
" [  A$ i) Q( K8 d0 I  d  2007 600002 err1 1
7 N' a* Z& K" W: U+ I  2008 600002 err1 1
/ S. O* }# O5 b* ^! V* v  规则也可以是多个维度不同取值,本例假定不同年份之间比较,比如要求2008年的’10’=2007年的’30’+’31’
7 i! w( E; \+ [$ w' z; e* k  SELECT year,code,
8 o0 ?) n5 U/ @5 [$ T! K$ ]  p_id, v1! v7 n4 i8 k/ H, Z
  FROM t603_27 O2 ]% K2 }& ~& \; ~% `# Z
  WHERE code IN (’600001’,’600002’)) R$ Y% J# b& t/ W
  MODEL RETURN UPDATED ROWS
- u  t/ U! j, X5 \, I  PARTITION BY (code)
2 R* {5 h) z2 v& M  DIMENSION BY (p_id,year)
" _5 |* V+ j' K5 v! u0 l. m2 e6 ^4 ]  MEASURES (v1)+ X& m) r: T& B3 l6 k' R$ d
  RULES (
, h  t/ K2 S" Y3 e2 B7 x  v1[’err1’,2008] = v1[’30’,2007] + v1[’31’,2007] -v1[’10’,2008])
% G1 {" c! O# M8 M) ^1 H  ORDER BY code, p_id;
9 L  b3 ~0 q3 q: B8 g* _  YEAR CODE P_ID V1  Y' [4 I6 ]1 M6 J# l* I7 J
  2008 600001 err1 00 H2 ], D8 \% M% S# w& w+ b
  2008 600002 err1 1& T( r3 e  s- n& X6 M0 U% l
  如果年份很多,每个年份都是和上年比较,这种描述可以用CV()函数简化0 e- f5 l' A7 t1 L& {
  SQL> insert into t603_2 select ’2006’ year,code,p_id,v1,v2 from t603_1;" Q1 X( s7 K' r
  SELECT year,code,! f9 c7 J, U& C
  p_id, v1( G" P! M9 S7 r; A5 A3 ~
  FROM t603_2* W( M. C2 E: g- K
  WHERE code IN (’600001’,’600002’)0 h& z! H6 O* t5 F! w* A: ]3 E
  MODEL RETURN UPDATED ROWS- x% u0 x/ r; K$ h4 ]
  PARTITION BY (code)
8 z; `0 P# z* ?  DIMENSION BY (p_id,year)7 l) ~$ b% }. g, k% B
  MEASURES (v1)
3 W2 u$ @$ Q) i* n9 w! U  RULES (1 N0 ~4 y  u! y8 T+ Y
  v1[’err1’,for year in( 2007 ,2008)] = v1[’30’,CV(year)-1] + v1[’31’,CV(year)-1] -v1[’10’,CV(year)])
* h! v% H: @. X* x/ `' n  ORDER BY code, p_id;" ^$ I; Q1 C. Y; J6 E+ x. _, p7 V
  YEAR CODE P_ID V1& {- ]3 _2 q! w$ b; [2 E0 }* A
  2007 600001 err1 0
+ u" [- w8 m, g2 `1 U3 [! a  2008 600001 err1 0
) w# v& ~$ n! z5 `, O* c  2007 600002 err1 1
. t6 e2 o2 ?) K; X$ [  2008 600002 err1 1
( w- @% G; ?% v* B% P, t$ |  如果year是数值类型,还可以用for year from 2007 to 2009 increment 1的语法,如果是其他类型,还可以用在in子句带子查询的办法,6 B" ?6 G/ h6 l0 p: A6 l- b$ y$ P
  比如for year in (select year from t603_2)。
7 d* s+ n7 q6 U& T, P. M  但需要注意不能采用year in 的语法,year in的语法只能符号引用已经存在的单元格,而v1[’err1’,x]是新单元格。
  v6 [7 `# v6 B  单个年份的写法如下:
- I  E" k7 Z8 }; i4 m  SELECT year,code,1 ?+ d0 v# P: f1 J7 V% \% G
  p_id, v1
2 t& O% a2 G* X- n& o/ z4 i  FROM t603_27 K' N; t& A, K5 u* X6 g
  WHERE code IN (’600001’,’600002’)
. v4 z4 `& H) _  MODEL RETURN UPDATED ROWS
! U8 V* u# ]: k: g  PARTITION BY (code)
+ C6 {2 P4 V! c7 ^  DIMENSION BY (p_id,year)
) o' A8 O0 \% w  }+ S8 {  MEASURES (v1)
. H4 K4 f8 e" c) Y  RULES (
8 r' E4 t* `$ `: `8 o4 S  v1[’err1’,2008] = v1[’30’,CV()] + v1[’31’,CV()] -v1[’10’,CV()])
* y5 O# i0 _" Q0 F# ~3 A9 r  ORDER BY code, p_id;! z( u# }) q3 L' z* v
  YEAR CODE P_ID V1
# N0 A: U* a7 y0 X! @  2008 600001 err1 0
& L: f5 _  Y; ~6 o0 F+ G5 _" h4 G  2008 600002 err1 1
5 k1 b$ S- F3 `' U: V" q  而; e# J' ~0 L: @, \- L) T; {8 z
  SELECT year,code,0 \& R+ {3 o, @% U
  p_id, v1$ a0 w, f0 q4 [) I% x! u7 ~0 t- L# j
  FROM t603_2* B, a( J$ j0 B( D, ~' _
  WHERE code IN (’600001’,’600002’)8 w6 K/ w2 m8 W
  MODEL RETURN UPDATED ROWS0 i. C$ B( c6 e( J+ T3 }# I( O
  PARTITION BY (code)
4 z) E2 B& |6 z% m$ x% g2 d$ b  DIMENSION BY (p_id,year)3 i6 K$ r) D5 M& f5 H
  MEASURES (v1)' ~) r# k. f; s. p
  RULES (+ f, I# k$ w) F  d  h. S
  v1[’err1’,year in (’2008’)] = v1[’30’,CV()] + v1[’31’,CV()] -v1[’10’,CV()])
% Y8 V! X; V. G4 [& {  则返回0行
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-21 13:44 , Processed in 0.249870 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表