oracle 行列統計轉換!!!

來源:互聯網
上載者:User

體會:要用decode /group by/ order by/sign/sum來實現不同的統計和不同報表的產生

--求hkb_test1中Y的值既是1,也是3,也是5的X
select * from hkb_test1;
X        Y
---- -----
a        1
b        1
a        3
d        2
e        4
f        5
a        5
d        3
d        6
b        5
c        4
b        3

結果:
X
----
a
b
--方法一
select x
  from hkb_test1
 group by x
having sum(decode(y, 1, -1, 3, -1, 5, -1, 0)) = -3;
--方法二
select x
  from hkb_test1
 group by x
having(sign(sum(decode(y, 1, -1, 0))) + sign(sum(decode(y, 3, -1, 0))) + sign(sum(decode(y, 5, -1, 0))) <= -3);

PS:  
    sign()函數根據某個值是0、正數還是負數,分別返回0、1、-1
所以可以用sign和decode來完成比較欄位大小來區分某個欄位。
select decode(sign(欄位1-欄位2),-1,欄位3,欄位4) from dual;

抄來的沒有弄的很明白的:
  sign是一個對於寫分析SQL有很強大的功能
  下面對sign進行一些總結:
  但屬性student取0和1以外的值,或者student取兩個以上的標法值,問題就不會這麼簡單了
  解決辦法就是特徵函數(abs(),sign())
  
  常用的特徵演算法
  [A=B]=1-abs(sign(A-B))
  [A!=B]=abs(sign(A-B))
  [A<B]=1-sign(1+sign(A-B)) 不能用-sign(A-B):因為如果不滿足A  
    [A<=B]=sign(1-sign(A-B))
  [A>B]=1-sign(1-sign(A-B))
  [A>=B]=sign(1+sign(A-B)))
  [NOTα]=1-d[α]
  [αANDb ]=d[α]*d[b]
  [αOR b ]=sign(d[α]+d[b ])
  
  例如:
  A<B             Decode( Sign(A-B), -1, 1, 0 )
  A<=B            Decode( Sign(A-B), 1, 0, 1 )
  A>B             Decode( Sign(A-B), 1, 1, 0 )
  A>=B            Decode( Sign(A-B), -1, 0, 1 )
  A=B             Decode( A, B, 1, 0 )
  A between B and C        Decode( Sign(A-B), -1, 0, Decode(Sign(A-C), 1, 0, 1 ))
  A is null          Decode(A,null,1,0)
  A is not null        Decode(A,null,0,1)
    A in (B1,B2,...,Bn)        Decode(A,B1,1,B2,1,...,Bn,1,0)
  nor LogA          Decode( LogA, 0, 1, 0 )   
  LogA and LogB         LogA * LogB
  LogA or LogB         LogA + LogB
  LogA xor LogB         Decode(Sign(LogA),Sign(LogB),0,1)
 
  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
select * from grade1;
STUDENTID SUBJECTID MARK
--------- --------- ----
      101 A01         59
      101 A02         72
      101 A03         90
      102 A01         75
      102 A02         91
      103 A01         71

--統計學生參加的考試成績
select STUDENTID,
       sum(decode(SUBJECTID,'A01', mark)) a,
       sum(decode(SUBJECTID,'A02', mark)) b,
       sum(decode(SUBJECTID,'A03', mark)) c
  from grade1
 group by STUDENTID;
STUDENTID          A          B          C
--------- ---------- ---------- ----------
      102         75         91
      101         59         72         90
      103         71           

--統計四種分數段的人數
select sum(case
             when mark < 60 then
              1
             else
              0
           end) as "not passed",
       sum(case
             when mark between 60 and 79 then
              1
             else
              0
           end) as "passed",
       sum(case
             when mark between 80 and 89 then
              1
             else
              0
           end) as "good",
       sum(case
             when mark >= 90 then
              1
             else
              0
           end) as "excellent"
  from grade1;
not passed     passed       good  excellent
---------- ---------- ---------- ----------
         1          3          0          2

--統計每年每個月的消費情況
select * from sale;
SUM_MONTH         SELL
--------- ------------
   200001      1000.00
   200002      1100.00
   200003      1200.00
   200004      1300.00
   200005      1400.00
   200006      1500.00
   200007      1600.00
   200101      1100.00
   200202      1200.00
   200301      1300.00

select substrb(sum_month, 1, 4) 年份,
         sum(decode(substrb(sum_month, 5, 2), '01', sell, 0)) 一月,
         sum(decode(substrb(sum_month, 5, 2), '02', sell, 0)) 二月,
         sum(decode(substrb(sum_month, 5, 2), '03', sell, 0)) 三月,
         sum(decode(substrb(sum_month, 5, 2), '04', sell, 0)) 四月,
         sum(decode(substrb(sum_month, 5, 2), '05', sell, 0)) 五月,
         sum(decode(substrb(sum_month, 5, 2), '06', sell, 0)) 六月,
         sum(decode(substrb(sum_month, 5, 2), '07', sell, 0)) 七月,
         sum(decode(substrb(sum_month, 5, 2), '08', sell, 0)) 八月,
         sum(decode(substrb(sum_month, 5, 2), '09', sell, 0)) 九月,
         sum(decode(substrb(sum_month, 5, 2), '10', sell, 0)) 十月,
         sum(decode(substrb(sum_month, 5, 2), '11', sell, 0)) 十一月,
         sum(decode(substrb(sum_month, 5, 2), '12', sell, 0)) 十二月
  from sale
 group by substrb(sum_month, 1, 4);
年份  一月   二月   三月   四月  五月   六月   七月   八月   九月  十月  十一月  十二月
---- ---- ------ ------ ------ ------ ------ ------ ------ ------ ----- ------ ------
2000  1000   1100  1200   1300   1400   1500  1600     0     0     0     0     0
2001  1100      0     0      0      0      0     0     0     0     0     0     0
2003  1300      0     0      0      0      0     0     0     0     0     0     0
2000     0   1200     0      0      0      0     0     0     0     0     0     0
 
Attention:統計中CASE的運用!!!
例子:
select * from hkb_case_test;
USERID EMPNO     SAL SEX
------ ----- ------- ---
     1 a         800   1
     1 a         800   1
     2 b         900   2
     3 a         400   1
     4 d        1400   2
     5 e        1200   1
     6 f         500   1
     7 a         300   2
     8 d        1000   1
     9 d        1230   2
    10 b        2000   2
    11 c        2000   1
    12 b        1200   1

select a.empno as 部門,
       count(a.userid) as 人數,
       sum(case a.sex
             when 1 then
              1
             else
              0
           end) as 男,
       sum(case a.sex
             when 2 then
              1
             else
              0
           end) as 女,
       sum(case sign(a.sal - 800)
             when -1 then
              1
             else
              0
           end) as 小於800元, --注意別名不能以數字開頭
       sum((case sign(a.sal - 800) * sign(a.sal - 1000) --用*來實現<和>功能
             when -1 then
              1
             else
              0
           end) + (case a.sal
             when 800 then
              1
             else
              0
           end)) as 從800至999,
            sum((case sign(a.sal - 1000) * sign(a.sal - 1200)
         when -1 then
          1
         else
          0
       end) + (case a.sal
         when 1000 then
          1
         else
          0
       end)) as 從1000元至1199元,
       sum((case sign(a.sal - 1200)
             when 1 then
              1
             else
              0
           end) + (case a.sal
             when 1200 then
              1
             else
              0
           end)) as 大於1200元
  from hkb_case_test a
 group by a.empno;

部門  人數   男   女  小於800元 從800至999 從1000元至1199元 大於1200元
---- ------ ---- ---- --------- ---------- ---------------- ----------
a     4      3    1      2          2             0             0
b     3      1    2      0          1             0             2
c     1      1    0      0          0             0             1
e     1      1    0      0          0             0             1
d     3      1    2      0          0             1             2
f     1      1    0      1          0             0             0

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.