如何为不存在的值创建行并使用0值填充计数?

时间:2014-11-27 03:11:41

标签: sql sql-server

在SQL Server中,我在数据的用户年龄组上运行查询,在某些年份,每个年龄组的用户数为零。例如,2013年的用户在" 18-21"年龄组,因此查询返回下一个年龄组," 22-25",作为第一行,因为没有包含" 18-21的条目。"相反,我想返回一个包含18-21的行,但是有0作为用户数的值。

目前,我有:

SELECT YEAR, AGE_GROUP, SUM(USERS) as usercount,
FROM USERS
WHERE YEAR = '2013'
AND PRIMARY_GROUP = 'NT'
GROUP BY YEAR, AGE_GROUP

返回:

YEAR  AGE_GROUP usercount
2014    22-25      200
2014    25-28       10

我希望它返回:

YEAR  AGE_GROUP usercount
2014    18-21       0
2014    22-25      200
2014    25-28       10

如何为不存在的特定值创建行,并使用0值填充计数?

为了记录,我实际上有一个名为' users'在users表中。令人困惑,我知道,但它是我接管的一个愚蠢命名的架构。 Users表包含关于我的用户报告的数据。它可能应该被命名为Users_Reporting。

4 个答案:

答案 0 :(得分:3)

我假设您有另一个包含Age Group所有行的表。

表名: AGEGROUPS

AGE_GROUP
18-21
22-25
25-28

试试这个:

SELECT '2014' AS YEAR, AG.AGE_GROUP, COALESCE(TB.usercount, 0) AS usercount
FROM (
    SELECT YEAR, AGE_GROUP, SUM(USERS) as usercount,
    FROM USERS
    WHERE YEAR = '2014'
    AND PRIMARY_GROUP = 'NT'
    GROUP BY YEAR, AGE_GROUP
) AS TB
RIGHT JOIN AGEGROUPS AG ON TB.AGE_GROUP=AG.AGE_GROUP

答案 1 :(得分:1)

您可以通过加入"假冒"年龄组+年份列表:

SELECT AGE_GROUPS.YEAR, AGE_GROUPS.AGE_GROUP, COALESCE(SUM(USERS), 0) as usercount
FROM (
    SELECT YEAR, AGE_GROUP
    FROM (
        SELECT '18-21' AS AGE_GROUP
        UNION SELECT '22-25'
        UNION SELECT '25-28'
    ) AGE_GROUPS, (SELECT DISTINCT YEAR FROM USERS) YEARS
) AGE_GROUPS
LEFT JOIN USERS ON (USERS.AGE_GROUP = AGE_GROUPS.AGE_GROUP AND USERS.YEAR = AGE_GROUPS.YEAR)
WHERE AGE_GROUPS.YEAR = '2014'
GROUP BY AGE_GROUPS.YEAR, AGE_GROUPS.AGE_GROUP

您也可以简化此操作,假设您的USERS表包含忽略特定年份的所有可能年龄组:

SELECT AGE_GROUPS.YEAR, AGE_GROUPS.AGE_GROUP, COALESCE(SUM(USERS), 0) as usercount
FROM (
    SELECT YEAR, AGE_GROUP
    FROM (SELECT DISTINCT AGE_GROUP FROM USERS) AGE_GROUPS, (SELECT DISTINCT YEAR FROM USERS) YEARS
) AGE_GROUPS
LEFT JOIN USERS ON (USERS.AGE_GROUP = AGE_GROUPS.AGE_GROUP AND USERS.YEAR = AGE_GROUPS.YEAR)
WHERE AGE_GROUPS.YEAR = '2014'
GROUP BY AGE_GROUPS.YEAR, AGE_GROUPS.AGE_GROUP

答案 2 :(得分:0)

假设所有年份和年龄组都在表格中(表格的某些行),那么您只需使用此表即可。我们的想法是使用cross join生成所有行,然后使用left join来引入您想要的值:

select y.year, ag.age_group, count(u.year) as usercount
from (select 2013 as year) y cross join
     (select distinct age_group from users) ag left join
     users u
     on u.year = y.year and u.age_group = ag.age_group and
        u.primary_group = 'NT'
group by y.year, ag.age_group;

我不知道sum(users)应该是什么。如果确实有列users.users,请将其与sum()一起使用。看起来你真的想要count()

答案 3 :(得分:-1)

试试这个...

SELECT YEAR, AGE_GROUP, isnull(Sum(USERS),0) as usercount,
FROM USERS
 WHERE YEAR = '2013'
AND PRIMARY_GROUP = 'NT'
GROUP BY YEAR, AGE_GROUP