2010-09-10 20 views
1

我有這樣的SQL查詢從表中檢索的ID有3列:ID,國家和年齡SQL查詢算上零

SELECT Country, 
(CASE 
WHEN AGE BETWEEN 0 AND 9 THEN '0-9' 
WHEN AGE BETWEEN 10 AND 19 THEN '10-19' 
WHEN AGE BETWEEN 20 AND 29 THEN '20-29' 
WHEN AGE BETWEEN 30 AND 39 THEN '30-39' 
WHEN AGE BETWEEN 40 AND 49 THEN '40-49' 
ELSE '50+' 
END) Age_Bins, COUNT (DISTINCT ID) 
FROM MYTABLE 
GROUP BY Country, Age_Bins; 

結果我得到的是這樣的:

UK '0-9' 7; 
UK '20-29' 14; 
etc... 

但我想要的還有英國'10-19'0(那個年齡段沒有ID)。如何修改sql代碼以使輸出數爲零。由於

回答

4

你可以創建每個年齡段作爲基於案例的列,返回0或1,並使用SUM(),而不是COUNT()

select V.country, sum(V.Zero2Nine) as [0-9], sum(V.Ten2Nineteen) as [10-19] ... 
from 
(
    select country, 
    (case when age between 0 and 9 then 1 else 0 end) as Zero2Nine, 
    (case when age between 10 and 19 then 1 else 0 end) as Ten2Nineteen 
    from ... 
) as V 

group by V.country 
+0

我喜歡這個解決方案,因爲它看起來很簡單,雖然它不直接使用「COUNT」。但是,我不知道它與上面介紹的第一種解決方案相比是否有任何缺點。 – francogrex 2010-09-10 19:17:32

+0

我在需要「容器」或「桶」的實際應用程序中始終使用此虛擬列方法。它執行速度快,結果準確。該查詢很容易理解和維護。我知道沒有缺點。如何進行投票? :-) – Tim 2010-09-11 11:23:09

+0

當然。我投了兩個解決方案,我給這個最好的答案:) – francogrex 2010-09-12 07:32:06

8

理想情況下你想要的「年齡箱」一張桌子和國家的表來使用這樣的:

select c.Country, b.age_bin, count(distinct m.id) 
from countries c 
cross join age_bins b 
left outer join mytable m on m.country = c.country 
          and m.age between b.min_age and b.max_age 

如果ncecessary您可以假冒的表是這樣的:

WITH countries as (select distinct country from mytable), 
    age_bins as (select '0-9' age_bin, 0 min_age, 9 max_age from dual 
        union all 
        select '10-19' age_bin, 10 min_age, 19 max_age from dual 
        union all 
        ... 
       ), 
select c.Country, b.age_bin, count(distinct m.id) 
from countries c 
cross join age_bins b 
left outer join mytable m on m.country = c.country 
          and m.age between b.min_age and b.max_age 
+0

+1我是一半w唉通過鍵入相同的答案:) – matja 2010-09-10 11:37:14

+0

該死,正是我的想法。除了我有'count(distinct)'部分錯誤。 – Constantin 2010-09-10 11:49:22