a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 397|回复: 1

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

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
 以产品产量表为例,一个工厂(用code表示)生产多种产品(用p_id表示),每种产品具有生产量(v1)和销售量(v2)
1 n8 y+ M3 J6 \: W! w  产品代码具有审核关系,比如’10’=’30’+’31’,其中’10’代表大类,’30’和’31’代表’10’大类下的小类。
# _, x9 F" t. p  \  SQL> create table t603 (code varchar(10),p_id varchar(7),v1 number(10),v2 number(10));2 A7 l6 y7 G- ~  d' R
  Table created.
% {! n3 \$ d; G3 K) M1 q  SQL> insert into t603 values(’600001’,’30’,1,1);. u5 S. t2 p, v5 l+ p
  SQL> insert into t603 values(’600001’,’31’,1,1);: s7 V* e4 M' M$ i8 O; y; O: o) w
  SQL> insert into t603 values(’600001’,’10’,2,2);
% N5 B' x/ _; p: m( Z( B9 j5 X  SQL> insert into t603 values(’600002’,’10’,3,2);  H7 w) J9 U2 B. m3 d
  SQL> insert into t603 values(’600002’,’31’,2,1);
4 B( y* i8 h$ n  SQL> insert into t603 values(’600002’,’30’,2,1);
' c0 ]% j" R7 ]- ~+ g  SQL> commit;
, K! o# G5 b2 E. f, r' O  Commit complete.
' {0 S7 e/ t6 T* V- y' }. M  z' b  SQL> select * from t603;
4 Y+ B* U5 G8 a  F  CODE P_ID V1 V2
  R9 |7 @2 V1 a: q  600001 30 1 18 D, f8 G1 `( `4 J2 v
  600001 31 1 17 t4 x5 u" @8 C# ~5 `
  600001 10 2 23 H& `8 i6 H) P1 C
  600002 10 3 2
% C6 F4 i4 {1 I% h- x4 O  600002 31 2 1
/ k1 x! q& h1 Q: S  600002 30 2 1, I/ ?0 I5 S" V# @' S- u. m
  6 rows selected.3 h, C% N$ O1 t$ {* a
  SELECT code,1 C  R2 s) H) V2 q, ]/ v
  p_id, v1
3 |' _5 A, w7 }, y3 I  [  FROM t603$ y! L- N/ X6 ]  U. q6 T: }4 _) x/ Z
  WHERE code IN (’600001’,’600002’)
7 e2 f/ a% A+ E" c. {$ O1 f  MODEL RETURN UPDATED ROWS2 M. J: L7 K# r8 m& \% A! o; x
  PARTITION BY (code)5 C. N0 b) C4 s) g6 K; S. f
  DIMENSION BY (p_id)
4 X0 E; b  D6 l+ }+ z9 @& L6 V/ Y  MEASURES (v1)
+ s2 H4 d: h  W- G: e  RULES (
# M; S( b5 Z- z. y6 l6 H2 c  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’]): p/ R, `8 J6 h% I7 g5 k
  ORDER BY code, p_id;8 L) o* E7 r1 R& r
  其中rule表示计算规则,’err1’表示这条审核关系的代号,它的值等于P_ID为’30’的v1值+P_ID为’31’的v1值-P_ID为’10’的v1值# e! u+ x- Q8 K* X% f# Q
  PARTITION BY (code)表示按工厂分区,即审核在一个工厂内的产品9 f/ R* K7 H! p2 f1 T8 s9 t$ T
  MODEL 关键字后面的 RETURN UPDATED ROWS 子句将结果限制为在该查询中创建或更新的那些行。使用该子句是使结果集只包含新计算的值,在本例中就是审核结果6 b, p1 m& t2 r2 Y8 K+ r) X* i
  CODE P_ID V1
5 j3 s5 c. e# S' q' h  600001 err1 0: F3 m: `" L1 g  W$ L) u+ D* F
  600002 err1 1. y: ~2 W' i/ F6 x0 T& Z! [# D
  如果返回值=0,表示v1[’30’] + v1[’31’] =v1[’10’]审核通过,否则,审核不通过
; _3 b4 O. t; N+ P6 e; D' O  A  SELECT code,/ W0 o5 C: I, Y  R- p0 M- J  T
  p_id, v1,v2
+ a% u/ v+ @* Z, e% M, t  FROM t603
' d" I, t, l* m/ I  WHERE code IN (’600001’,’600002’)+ T5 t. D2 T* B' d" g
  MODEL RETURN UPDATED ROWS' Z" D: S6 m6 `" s& C4 R% B
  PARTITION BY (code)
5 A, P) M4 J! U" O  DIMENSION BY (p_id)& Y+ S  `0 ]4 D( _
  MEASURES (v1,v2)
( b9 E0 b  }( i7 u2 L* x8 j7 @  RULES (0 q1 Q+ I1 k( \# {$ O8 V
  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’],
5 S1 S# [- T: n  v2[’err1’] = v2[’30’] + v2[’31’] -v2[’10’])
, j. R  G/ E6 J: y  ORDER BY code, p_id;* J# I; H: Z# D3 T
  CODE P_ID V1 V26 A# h) X% ~) ], w/ l
  600001 err1 0 0; [, u0 E1 H2 d8 Z5 n2 C) F+ p
  600002 err1 1 0
( m4 t% t2 m4 }8 u' S  z  如果表格中包含多个维度的数据,比如时间,多个维度都可以编写规则,比如2008年的审核关系
5 A+ K$ P1 E2 p1 G( S! b  SELECT year,code,0 @  e  Z; e  h& v+ [. Z% N: K2 m
  p_id, v17 x2 }* q; ^7 b3 X7 R5 }
  FROM t603_1& v( M0 L: A  l7 W0 S8 L  u
  WHERE code IN (’600001’,’600002’)9 g+ O* V- j* `
  MODEL RETURN UPDATED ROWS  @" `: x  f, E# Z. ?. C+ q
  PARTITION BY (code)$ d& v- A4 ^+ R4 {' v) F. B6 J
  DIMENSION BY (p_id,year)
9 d- P. X2 }7 a, e( [" |: R0 U) u  MEASURES (v1)8 o. m5 K1 s1 o# r+ Y
  RULES (8 i( x; t& M- t0 i
  v1[’err1’,2008] = v1[’30’,2008] + v1[’31’,2008] -v1[’10’,2008])  C  l" y0 [+ I+ U4 Y# o: d
  ORDER BY code, p_id;1 M/ C$ U. Y7 H: X# I5 q
  YEAR CODE P_ID V1' E, C/ r4 V$ f  x' T
  2008 600001 err1 06 I% R# |' a- y5 J, g7 u- J+ Y" y8 J
  2008 600002 err1 1( V" A2 F# i/ A8 s5 ]' Z
  如果维度不影响规则,也可以只分区,而沿用原来的规则' [. ~1 Z: }: s8 \' ~2 z, E) B: D  R4 V4 I
  SELECT year,code,. J5 h, |1 _. k- E
  p_id, v1
  x8 _1 L; R5 Y0 [  FROM t603_16 B# L9 i: s8 V7 I
  WHERE code IN (’600001’,’600002’)0 l( e) M  K5 o0 C: x( g7 S
  MODEL RETURN UPDATED ROWS1 Y% j. r( E+ _
  PARTITION BY (code,year)
# h+ q+ P; I3 y7 [' _' T4 e+ e( q  DIMENSION BY (p_id)
8 F" T" ]5 @; S% B) \" U$ a  MEASURES (v1)  A; x9 D( M: J! W
  RULES (
# {# A' i1 ^! A9 z! B9 J) W& |  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’])
% P7 }: l% ^) x" K  ORDER BY code, p_id;
7 N# a) c, R, r; C' \  YEAR CODE P_ID V1
; ?7 }6 [. G( C  M0 m  2008 600001 err1 0# b# Z$ |4 g) l+ O5 ]
  2008 600002 err1 1
! l" J5 v0 x: ?% s  SQL> create table t603_2 as select * from t603_1;% W( j! V* ~" N6 m7 Y
  Table created.1 Z# L7 ^! ?) Y5 E4 z7 Z, n' h
  SQL> insert into t603_2 select ’2007’ year,code,p_id,v1,v2 from t603_1;
1 V% }$ T, E) p, P  6 rows created.
回复

使用道具 举报

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

Oracle10g的MODELSQL进行行间计算

 如果表中具有多个年份的数据,每个年份的审核结果都能显示0 u4 d# j- a' U! K% Z; y. b
  SELECT year,code,5 F4 o$ S$ l( J3 V- }0 S
  p_id, v1
6 I9 f; a- I) O1 r  FROM t603_2) }$ L3 j; Y$ b3 q
  WHERE code IN (’600001’,’600002’)
: W( n$ v8 J* w* v) B  MODEL RETURN UPDATED ROWS6 d, f; F1 B: S, J! F7 _) W3 c
  PARTITION BY (code,year)
% r7 f& Q+ s/ C+ B* H  DIMENSION BY (p_id)
) f) L' q1 H  F- Y6 P  U  MEASURES (v1)
2 U& n5 Z/ ]9 S& I  RULES (8 X! S' p. z8 K" R2 |
  v1[’err1’] = v1[’30’] + v1[’31’] -v1[’10’])% e8 {( K/ S, J
  ORDER BY code, p_id;
& |* G' c# g( w, a  YEAR CODE P_ID V1
. q8 s+ ?" R* i9 m# t- E  2008 600001 err1 02 F2 s$ G$ M# ^8 X$ b' b1 n
  2007 600001 err1 0/ @4 }" F/ c  E0 F# X
  2007 600002 err1 10 h! F; f. m0 ]+ }
  2008 600002 err1 1
# r8 p- x8 W4 ^8 r& G5 i0 _  规则也可以是多个维度不同取值,本例假定不同年份之间比较,比如要求2008年的’10’=2007年的’30’+’31’- A/ u. Q/ S9 ]8 A3 i+ P; @
  SELECT year,code,8 f1 y& u! p/ K5 n9 \
  p_id, v1$ ?0 t" g3 K- A9 p
  FROM t603_23 F1 r( N0 I3 \8 W/ z' ?+ Z
  WHERE code IN (’600001’,’600002’); a  @2 H5 l' L7 K1 O6 y$ s: D
  MODEL RETURN UPDATED ROWS* f7 C  d8 e# n4 B6 ]
  PARTITION BY (code)
9 J+ }4 p; z7 x  DIMENSION BY (p_id,year)
2 j2 O! W7 y; E% I  MEASURES (v1)
( Y8 N/ X0 \& ]: j: Q* V  RULES (
. \2 ^3 c0 I& r/ J3 J. s  v1[’err1’,2008] = v1[’30’,2007] + v1[’31’,2007] -v1[’10’,2008])
2 C/ \' o# K* F1 I1 L0 g  ORDER BY code, p_id;# c" V  b3 n! S/ g" N
  YEAR CODE P_ID V1: a0 l  d* |/ n/ d
  2008 600001 err1 0
5 t' [+ r( K; V7 t! J0 E- B/ `9 R  2008 600002 err1 1
& U9 [/ u/ ]; _4 j  如果年份很多,每个年份都是和上年比较,这种描述可以用CV()函数简化. Y6 N. U: i& M& l8 i" v
  SQL> insert into t603_2 select ’2006’ year,code,p_id,v1,v2 from t603_1;4 K' U: z  F4 d7 F! J
  SELECT year,code,
9 N0 ], m' B' U6 a" u+ I. I  p_id, v11 W6 t' z9 q- r  Y2 P. A
  FROM t603_2
6 i! \& _9 O3 p2 {3 r/ ^3 J5 d  WHERE code IN (’600001’,’600002’)- M8 W5 ^- H9 b
  MODEL RETURN UPDATED ROWS1 q- L2 x% [/ A6 F1 }8 }' D
  PARTITION BY (code)- ]/ _- ^- L& O; A( |: f3 s
  DIMENSION BY (p_id,year); h0 l! R1 q. u( U1 P+ ?8 I  I8 u8 b0 S
  MEASURES (v1)
  ^8 E1 j+ n; D$ f7 @+ F  RULES () {- }9 S+ N& F" i9 P
  v1[’err1’,for year in( 2007 ,2008)] = v1[’30’,CV(year)-1] + v1[’31’,CV(year)-1] -v1[’10’,CV(year)])3 B/ z6 \; h# Z/ ~2 \0 B
  ORDER BY code, p_id;
9 `9 }6 F4 b& ?, ]  YEAR CODE P_ID V1
: u6 i2 o9 ]5 Z# [8 u# `4 L  2007 600001 err1 0
/ O5 ~' p- O- v6 P  2008 600001 err1 0) k' |7 E7 j  A% Y/ A7 }& @+ T
  2007 600002 err1 1+ i0 O" Q* b% W& i1 }
  2008 600002 err1 1
1 N0 w2 y" j7 g; S" a3 G0 _  如果year是数值类型,还可以用for year from 2007 to 2009 increment 1的语法,如果是其他类型,还可以用在in子句带子查询的办法,
( \  w+ n" i0 m) W; j$ b0 h; i  比如for year in (select year from t603_2)。
+ p" O) ~% K7 W+ s0 Q$ C  但需要注意不能采用year in 的语法,year in的语法只能符号引用已经存在的单元格,而v1[’err1’,x]是新单元格。! T+ w# i9 o* _% V$ b
  单个年份的写法如下:8 P( c# l3 A& M' e: u
  SELECT year,code,
. j* `0 Q& E0 z* y  p_id, v1. q, e. N1 Q  R: Z: d
  FROM t603_2; x& q) b6 {  R6 y! G; F6 f) |
  WHERE code IN (’600001’,’600002’)- u' O/ }- S* I0 L. C
  MODEL RETURN UPDATED ROWS: G" X* h/ U+ n4 Z" \
  PARTITION BY (code)
& r0 [# @, V# T% j# e! V  DIMENSION BY (p_id,year)
! I) r& \( W4 q7 k. E6 c" `' {  MEASURES (v1)
9 n% C- Z: {. Z! f$ `7 f  RULES (
7 x& n, w- k( ~3 k6 j# F5 s  v1[’err1’,2008] = v1[’30’,CV()] + v1[’31’,CV()] -v1[’10’,CV()])4 N) A% J/ K# {4 \. t* `* ~
  ORDER BY code, p_id;
  K6 ]) F2 l% r$ c% M  YEAR CODE P_ID V12 x+ u' A3 c0 t! V0 q8 R& [3 ?; @0 p
  2008 600001 err1 0: U" g/ [* M9 p7 |' z1 X: q
  2008 600002 err1 1/ h$ J* T( `0 c  g# N$ X
  而& Z' f. ^' J: ^  F+ d0 p: |' x
  SELECT year,code,
, Y6 T0 K5 X6 z2 E8 ]0 t. A  p_id, v1
% Z) s2 ?% b$ e2 K( T" ^( f5 p  FROM t603_2
- D2 w! A% U( y' |  WHERE code IN (’600001’,’600002’)6 ^$ O$ W8 H; O6 w% n1 F. F
  MODEL RETURN UPDATED ROWS/ S6 x% S# o5 S3 J# ~9 o
  PARTITION BY (code)1 k  _3 K3 B& E4 E
  DIMENSION BY (p_id,year)1 r# x+ a% w0 \$ t- g- k
  MEASURES (v1)) Y; C. v" X+ _" U
  RULES (/ Z$ [( {+ C2 m) e! d/ P
  v1[’err1’,year in (’2008’)] = v1[’30’,CV()] + v1[’31’,CV()] -v1[’10’,CV()])  j* @& f# D  ~( |; `* T- R
  则返回0行
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 12:39 , Processed in 0.671687 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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