回答

收藏

我该如何在Oracle中编写SQL?

技术问答 技术问答 34 人阅读 | 0 人回复 | 2023-09-13

所以,这是表格-
' d3 @( d: s1 Fcreate table person ($ u: j; w9 ^  D8 L
id number,
/ Z( s4 \! A) F" q, aname varchar2(50)
) y3 k6 G5 F! g: G0 F);/ g) `9 m3 q3 x: J  v
create table injury_place (
8 P0 L( \( T/ \3 Wid number,4 \7 v- {8 U8 {3 c! C- K; R0 _8 H
place varchar2(50)
6 P5 P% @/ h$ J, B, j9 b2 r);
/ u! L" p3 \5 l. N: \7 ecreate table person_injuryPlace_map (
7 B9 j7 r# x  h# E/ @person_id number,+ m$ X) B& F, q3 n( p  _
injury_id number
9 i8 s# D5 ], u) A0 Q: R);) Y" ?" @+ d2 o3 a  s" Z( U3 N& \
insert into person values (1, 'Adam');
8 R( v3 {9 ?7 K/ A9 F: D8 _( einsert into person values (2, 'Lohan');7 w) E) g7 L1 ~& K
insert into person values (3, 'Mary');
! q% y5 J) _* F& l/ ]4 |insert into person values (4, 'John');
! }4 G) X) E& O3 \% i" n9 q; cinsert into person values (5, 'Sam');8 ]7 q5 C/ {3 [5 o8 x

5 z2 S2 P- @$ q" O& Q1 Uinsert into injury_place values (1, 'kitchen');. E1 A; H9 K2 Z) U! h* t' q
insert into injury_place values (2, 'Washroom');
  c, q) \. e- ?6 K" ]  f" X% J0 {  tinsert into injury_place values (3, 'Rooftop');- Q$ @% w. s- ]& z
insert into injury_place values (4, 'Garden');- p: X3 S5 m% B+ J8 T

+ A4 B+ Y* F2 E2 u% C+ T! Pinsert into person_injuryPlace_map values (1, 2);. b+ Y  V" x+ M; [* p- E8 \6 N
insert into person_injuryPlace_map values (2, 3);9 Z1 o# {8 H6 l6 f4 ?
insert into person_injuryPlace_map values (1, 4);
, Y; J; p" u" l9 I% w, p4 iinsert into person_injuryPlace_map values (3, 2);' N7 L. v5 w! ]0 K$ j* s
insert into person_injuryPlace_map values (4, 4);
; ~! I2 e: l+ ]1 x5 kinsert into person_injuryPlace_map values (5, 2);9 w  Q' ^' J4 X
insert into person_injuryPlace_map values (1, 1);; j2 ~/ \# ]+ q1 {' I
在这里,表格person_injuryPlace_map只会映射其他两个表格。
2 Q, {7 d! `6 l1 {/ d我想要显示数据的方式是-! m) e3 S" I) K; B3 m& ^, x: M
Kitchen   Pct      Washroom   Pct     Rooftop   Pct     Garden   Pct  }9 o( Z# e% [0 z, D- x
-----------------------------------------------------------------------1 O7 w1 M/ x! F& A! l8 ~( e( W" o! }
1         14.29%   3          42.86%   1        14.29%   2        28.57%5 D' r* K# E) z4 u" x0 b& T+ o  s2 s6 m
在这里,“厨房”,“洗手间”,“屋顶”,“花园”列的值是发生的事件总数。“百分比”列将显示总计数的百分比。+ \) k. b; K' F3 h" J3 t
如何在Oracle SQL中做到这一点?# ^  z$ k0 O+ D9 a
               
8 i* B& ?6 q0 I7 M3 k解决方案:
; D% q# C* y$ Z  n. u) t& B- V0 G                2 {* w1 Q/ W; J
4 t) ~4 J+ E/ |' F7 x

- a* A- i- f$ v8 u9 P* h: A6 b2 ~                您需要使用标准的 PIVOT 查询。
# Q( a9 Q" X6 D( a1 A4 J+ s根据您的 Oracle数据库版本 ,您可以通过以下两种方式进行操作:
! ?  |% M+ v. sPIVOT 用于 11g 及更高 版本9 F/ p! S( K0 X% N: h9 E) v7 }
SQL> SELECT *2 z  G6 }  K1 g$ v  f; V/ p0 B! e
  2  FROM
4 d* @( f9 p, W" D; Z) Y0 X  3    (SELECT c.place place,
1 M/ g4 ?* R/ H7 z  f/ {, E! u  4      row_number() OVER(PARTITION BY c.place ORDER BY NULL) cnt,
' B, |2 b" Q2 [& Y4 O( r. m  5      (row_number() OVER(PARTITION BY c.place ORDER BY NULL)/' H" M! L( [% S
  6      COUNT(place) OVER(ORDER BY NULL))*100 pct" a3 Q2 b, b/ N( F
  7    FROM person_injuryPlace_map A
% g' F3 R1 _. P6 N* F  8    JOIN person b
# D& q3 z3 V9 f7 J) I  9    ON(A.person_id = b.ID)
% z9 Z1 Z1 P- {8 O 10    JOIN injury_place c; B& S2 m) ^- z" s
11    ON(A.injury_id = c.ID)+ z" U* t8 m# `
12    ORDER BY c.place
9 \9 T/ ?, }5 x9 Q3 w. \- H; ?/ e 13    ) PIVOT (MAX(cnt),! E. R+ p# ]6 w' H# s9 W2 c
14             MAX(pct) pct
4 e/ Z1 p3 J! p' A, c$ o( ]9 D 15             FOR (place) IN ('kitchen' AS kitchen,2 }- B* `8 f, `, b
16                             'Washroom' AS Washroom,
2 \7 K6 w  w/ G7 d7 t. A' M. X 17                             'Rooftop' AS Rooftop,
; A; ~( K* S  f: Y% z 18                             'Garden' AS Garden));6 ]& i9 _/ B1 @: U
   KITCHEN KITCHEN_PCT   WASHROOM WASHROOM_PCT    ROOFTOP ROOFTOP_PCT     GARDEN GARDEN_PCT) O$ B8 Y; Z& _) i
---------- ----------- ---------- ------------ ---------- ----------- ---------- ----------
7 ]; i8 C% k: t5 S/ X! j5 b         1  14.2857143          3   42.8571429          1  14.2857143          2 28.5714286
7 l3 f5 w& B2 J+ b% k. i5 r版本10g* 及之前的 版本中 使用 MAXDECODE*9 @* t0 C/ @1 S! x# O
SQL> SELECT MAX(DECODE(t.place,'kitchen',cnt)) Kitchen ,
+ x" ^( j- ~0 m: b9 z1 w6 E  2    MAX(DECODE(t.place,'kitchen',pct)) Pct ,# D: b! X. R. w/ q$ z- ?
  3    MAX(DECODE(t.place,'Washroom',cnt)) Washroom ,
7 s" V- T  j: w- G; e' q- S) @1 w  4    MAX(DECODE(t.place,'Washroom',pct)) Pct ,, w  n" O8 T, X" l6 r) x! j
  5    MAX(DECODE(t.place,'Rooftop',cnt)) Rooftop ,
. |4 D9 o8 @; s- A  Q& D  6    MAX(DECODE(t.place,'Rooftop',pct)) Pct ,* u0 }1 T, O( J4 \/ G$ U! \3 {( m* x; u
  7    MAX(DECODE(t.place,'Garden',cnt)) Garden ,
' {, d, a- N* v$ M7 c  8    MAX(DECODE(t.place,'Garden',pct)) Pct
) d! c+ N# H+ l  9  FROM2 ?, X. x! O# f! K" d% c1 J. ?
10    (SELECT b.ID bid,
' Q4 E: T4 M% J 11      b.NAME NAME,/ g. `" w' A: T+ l1 u
12      c.ID cid," T) K2 G* @! C& o8 O
13      c.place place,& Z; u8 Z* b. A7 ~/ T/ M) A
14      row_number() OVER(PARTITION BY c.place ORDER BY NULL) cnt,* A* a( r( q1 A3 a1 l' n8 A
15      ROUND((row_number() OVER(PARTITION BY c.place ORDER BY NULL)/
$ I7 v& H" O0 S: G$ r  i6 M 16      COUNT(place) OVER(ORDER BY NULL))*100, 2) pct/ F( ^: o  ~7 G, v8 q+ F
17    FROM person_injuryPlace_map A
0 ^; |! E( m0 \- n3 H 18    JOIN person b- C. ^% }4 Y  C9 Z' T" ]3 X
19    ON(A.person_id = b.ID). j- Z' D. K) P. j- ^+ ]6 `) Z/ q
20    JOIN injury_place c
5 M  s) @+ j! ?  ~+ M. S 21    ON(A.injury_id = c.ID)
1 }! ~& P1 Y9 K+ _ 22    ORDER BY c.place
! N1 f7 F" a+ d: r# Y 23    ) t;
7 N9 p; n. m# M6 {   KITCHEN        PCT   WASHROOM        PCT    ROOFTOP        PCT     GARDEN        PCT. ^; u' u  p% Q: D4 z
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------0 R- u9 G8 R# k. X. C4 |' ~5 j
         1      14.29          3      42.86          1      14.29          2      28.57
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则