2012-02-06 288 views
1

請考慮這一形象:如何使用GROUP BY來計算區間

enter image description here

我有這樣的一個表:

Age    Active   Men/Women 
------------------------------------------------- 

我想寫一個查詢,calulate Count的每年齡間隔爲男性和女性。我不知道我可以如何使用GROUP BY和間隔。

在我的報告在上面的圖像的左側我想計算UnActive rows.How我可以合併這個查詢一個查詢?

感謝

+0

你可以粘貼你的表格數據與結構 – 2012-02-06 12:30:47

+0

數據的呈現方式不同於數據來自數據庫的方式。你上面有什麼是非常人爲的 – gbn 2012-02-06 12:37:07

+1

'800'和'200' ='500'的'Total'如何? 「417.5」來自哪裏?你的意思是「平均」而不是「總計」? – Seph 2012-02-06 12:56:45

回答

2
SELECT 
    Active.State, 
    Age.Base, Age.Base+4, 
    COUNT(*) AS TotalCount, 
    COUNT(CASE WHEN T.[Men/Women] = 'man' THEN 1 END) AS ManCount, 
    COUNT(CASE WHEN T.[Men/Women] = 'woman' THEN 1 END) AS WomanCount 
FROM 
    (
    VALUES (10),(15),(20),(25),(30),(35),(40) /*.. add the rest */,(90),(95) 
    ) AS Age(base) 
    CROSS JOIN 
    (
    VALUES (0), (1) 
    ) AS Active(State) 
    LEFT JOIN 
    MyTable T ON T.Age BETWEEN Age.Base AND Age.Base+4 AND T.Active = Active.State 
GROUP BY 
    Active.State, 
    Age.Base, Age.Base+4; 

在此之後,你可以格式化你想怎麼

編輯生成空範圍

+0

小節中留下組中的「AGE_INTERVAL」部分標籤,謝謝@gbn,您的代碼在'AS'中有2個problem.first錯誤, GROUP BY' clause.second當我用@Seph數據運行你的代碼時,我得到了2行30-34。 – Arian 2012-02-06 18:00:41

+0

@羅欣:正確的,一個不活躍的女性,一個活躍的男性 – gbn 2012-02-06 18:04:33

+0

謝謝@ gbn.there是另一個問題。在我的報告中,當間隔沒有值時,我應該顯示零列。如何更改您的查詢以將所有間隔分組?非常感謝 – Arian 2012-02-06 20:59:12

1

可以GROUP BY年齡區間的情況:

SELECT 
    COUNT(*) AGE_COUNT, 
    CASE WHEN AGE BETWEEN 15 AND 19 THEN 'Age 15-19' 
     WHEN AGE BETWEEN 20 AND 24 THEN 'Age 20-24' 
     ELSE 'Other' 
    END AGE_INTERVAL 
FROM 
    YOUR_TABLE 
GROUP BY 
    CASE WHEN AGE BETWEEN 15 AND 19 THEN 'Age 15-19' 
     WHEN AGE BETWEEN 20 AND 24 THEN 'Age 20-24' 
     ELSE 'Other' 
    END  
+0

我用@Seph數據運行了你的查詢,但它只是拖動了2行'年齡20-24 ---------其他' – Arian 2012-02-06 18:15:18

1

這應該工作:

SELECT SUM(CASE WHEN [Men/Women] = 'M' THEN 1 ELSE 0 END) AS Men, 
SUM(CASE WHEN [Men/Women] = 'W' THEN 1 ELSE 0 END) AS Women, 
COUNT(*) as Total, 
CASE WHEN Age BETWEEN 10 AND 14 THEN 'Age 10-14' 
    WHEN Age BETWEEN 15 AND 19 THEN 'Age 15-19' 
    WHEN Age BETWEEN 20 AND 24 THEN 'Age 20-24' 
    ELSE 'Old' 
END Age 
FROM MyTable 
WHERE Active = 1 
GROUP BY  CASE WHEN Age BETWEEN 10 AND 14 THEN 'Age 10-14' 
    WHEN Age BETWEEN 15 AND 19 THEN 'Age 15-19' 
    WHEN Age BETWEEN 20 AND 24 THEN 'Age 20-24' 
    ELSE 'Old' 
END 
+0

我用@Seph數據運行了你的查詢,但它只是拖動了2行'年齡20- 24 -----舊' – Arian 2012-02-06 18:13:37

1

實際上,你可以從擴大安德烈什麼...提供

SELECT 
    CASE WHEN YT.AGE BETWEEN 15 AND 19 THEN 'Age 15-19' 
     WHEN YT.AGE BETWEEN 20 AND 24 THEN 'Age 20-24' 
     ELSE 'Other' 
    END AGE_INTERVAL, 
    SUM(CASE WHEN YT.Active THEN 1 ELSE 0 END) as ActiveCount, 
    SUM(CASE WHEN YT.Gender = 'M' THEN 1 ELSE 0 END) as MaleCount, 
    SUM(CASE WHEN YT.Gender = 'F' THEN 1 ELSE 0 END) as FemaleCount, 
    COUNT(*) AgeGroupCount 
FROM 
    YourTable YT 
GROUP BY 
    Age_Interval 
+0

謝謝@ DRapp.I跑了你我有這個錯誤:'無效的列名'Age_Interval'.' – Arian 2012-02-06 18:08:57

+0

@羅欣,它可能是一個SQL服務器的事情與MySQL ...您可能需要複製整個大小寫/當用於創建Age_Interval列時,只需在第 – DRapp 2012-02-06 19:06:21

1

正如其他人所說,這是試圖在一個方式,是不一樣的你的數據在所有的報告。

但我認爲最好的方式實現這一目標SQL中是創建一個標量函數(道具@gbn的最小/最大年齡範圍邏輯):

CREATE FUNCTION usvf_calculate_age_bracket 
(
    -- Add the parameters for the function here 
    @age INT 
) 
RETURNS VARCHAR(50) 
AS 
BEGIN 
    -- Return the result of the function 
    RETURN CAST(@age/5*5 AS VARCHAR(20)) + '-' + CAST(@age/5*5+4 AS VARCHAR(20)) 
END 
GO 

然後在你的查詢,你可以這樣做:

SELECT SUM(CASE WHEN gender = 'F' THEN active ELSE 0 END) AS [Women], 
    SUM(CASE WHEN gender = 'M' THEN active ELSE 0 END) AS [Men], 
    SUM(CAST(active AS int)) AS [Total], 
    'Age ' + dbo.usvf_calculate_age_bracket(age) AS [Age] 
FROM myTable 
GROUP BY dbo.usvf_calculate_age_bracket(age) 

我的測試代碼:

DECLARE @T TABLE 
(
age int, 
active bit, 
gender char(1) 

) 

INSERT INTO @T VALUES (25, 1, 'M'),(32, 0, 'F'),(21, 1, 'M'),(22, 1, 'F'),(28, 1, 'F'),(32, 0, 'M'), (23, 1, 'M'),(42, 0, 'F'),(29, 1, 'M'),(29, 1, 'F'),(28, 1, 'F'),(32, 1, 'M') 

SELECT SUM(CASE WHEN gender = 'F' THEN active ELSE 0 END) AS [Women], 
SUM(CASE WHEN gender = 'M' THEN active ELSE 0 END) AS [Men], 
SUM(CAST(active AS int)) AS [Total], 
'Age ' + dbo.usvf_calculate_age_bracket(age) AS [Age] FROM @T 
GROUP BY dbo.usvf_calculate_age_bracket(age) 

結果:

Women Men Total Age 
1 2 3  Age 20-24 
3 2 5  Age 25-29 
0 1 1  Age 30-34 
0 0 0  Age 40-44 

這似乎接近你想要的,它並不是一個過分複雜的SQL查詢來實現這一點。 (除了我不能計算出你的'總'列)

+0

感謝您的博文很棒 – Arian 2012-02-07 08:33:16