Oracle 學會怎麼樣分解複雜的問題

來源:互聯網
上載者:User

//問題  
表TEST:  
ID 姓名 消費 日期 退休標誌(1-在崗,2-退休)  
004 張三 20 2010-05-11 1  
007 李四 50 2010-06-23 1  
002 王五 10 2010-06-23 2  
004 張三 100 2010-07-20 2  
//按退休標誌分組,統計消費人次和金額,結果為:  
退休標誌 消費人次 消費  
1 1 50  
2 3 130  
//註:張三在2010-07-20已退休,之前的在崗消費則以退休來統計人次和消費金額  
//解法:  
//問題分析:  
//如果此題只是統計在崗和退休的人員的話,會是一個簡單的查詢語句:  
select 退休標誌 flag,count(*) cnt,sum(消費) amount  
from test  
group by 退休標誌;  
//但是這裡有一個關鍵問題就是,同一個人在不同的時間段的退休標誌不一樣,  
//也就是以前在崗,後來退休了;  
//剛剛碰到此問題的時候,或許沒有什麼思路,對於處理同一個人,在不同時間段的退休標誌不一;  
//其實有了上面那個查詢的基礎,我們就可以解決此問題了;  
//我們所要做的就是將表中所有退休的人員的退休標誌修改為2即可;  
//這麼一來我們就要用到內嵌視圖:  
//下面我們就來修改一下已經退休了的人員的退休標誌:  
//這裡所說的修改,不是update表,而是做一個標誌:  
with test as (  
     select '004' id,'張三' name,20 amount,date'2010-05-11' pdate,1 flag from dual union all  
     select '007','李四',50,date'2010-06-23',1 from dual union all  
     select '002','王五',10,date'2010-06-23',2 from dual union all  
     select '004','張三',100,date'2010-07-20',2 from dual)  
select t.*,  
       case 
           when (select count(*)  
                 from test a  
                 where a.id=t.id  
                   and a.flag=2)>0  
           then 2  
           else 1  
       end newflag  
from test t  
/  
ID  NAME     AMOUNT PDATE             FLAG    NEWFLAG  
--- ---- ---------- ----------- ---------- ----------  
004 張三         20 2010-05-11           1          2  
007 李四         50 2010-06-23           1          1  
002 王五         10 2010-06-23           2          2  
004 張三        100 2010-07-20           2          2  
//上面這個case就是將已退休人員的退休前標誌從1標記為2;  
//裡層的when部分使用到了一個表自串連的查詢:  
select a.id,count(*) cnt  
from test a,test b  
where a.id=b.id  
  and a.flag=2  
group by a.id  
/  
ID         CNT  
--- ----------  
002          1  
004          2  
//這個子查詢就是為了將已退休人員的id號找出來,  
//並在case語句中,將這些id號為已退休的退休標誌設定為2,  
//這就是上面那個查詢裡面我們看到的newflag  
//然後作為新的退休標誌,用於主查詢中  
//最後,我們來看看怎麼構造最開始提出的那個簡單的查詢:  
with test as (  
     select '004' id,'張三' name,20 amount,date'2010-05-11' pdate,1 flag from dual union all  
     select '007','李四',50,date'2010-06-23',1 from dual union all  
     select '002','王五',10,date'2010-06-23',2 from dual union all  
     select '004','張三',100,date'2010-07-20',2 from dual)  
select newflag flag, count(*) cnt, sum(amount) amount  
from (select t.*,  
             case 
                 when (select count(*)  
                       from test a  
                       where a.id = t.id  
                         and a.flag = 2) > 0   
                 then 2  
                 else 1  
             end newflag  
        from test t)  
group by newflag  
/  
      FLAG        CNT     AMOUNT  
---------- ---------- ----------  
         1          1         50  
         2          3        130  
//小結:  
//碰到問題,要細心的分析,竟可能的將問題分解,也就是將大事化小,小事化了,  
//最後,在將這些分解了的小問題綜合起來,就可以解決大問題了 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.