如何使用GROUP BY计算间隔

时间:2012-02-06 12:24:22

标签: sql sql-server sql-server-2008

请考虑此图片:

enter image description here

我有一张这样的表:

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

我想写一个查询,为每个年龄段的男性和女性制定Count。我不知道如何使用GROUP BY和间隔。

在我上面图片左侧的报告中,我想计算UnActive行。如何将其合并到查询到一个查询?

感谢

5 个答案:

答案 0 :(得分: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;

在此之后,您可以按照自己的方式格式化

编辑生成空范围

答案 1 :(得分:1)

您可以按年龄间隔CASE进行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    

答案 2 :(得分: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

答案 3 :(得分:1)

你实际上可以从Andrea提供的内容中扩展......

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

答案 4 :(得分: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查询。 (除了我无法解决你的'总'专栏)