//問題
表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
//小結:
//碰到問題,要細心的分析,竟可能的將問題分解,也就是將大事化小,小事化了,
//最後,在將這些分解了的小問題綜合起來,就可以解決大問題了