GroupBy返回限制之外的结果

时间:2016-03-15 14:18:36

标签: sql sql-server

我正在尝试为分组但在where语句之外的数据包含默认值。

表格

Name    Location
-----------------------
Chris   North
John    North
Jane    North-East
Bryan   South

查询

SELECT 
    Location,
    COUNT(*)
FROM Users
WHERE Location = 'North' OR Location = 'North-East'
GROUP BY Location

输出

North   2
North-East  1

所需输出

North   2
North-East  1
South   0

是否可以为where子句之外的每个位置返回零?

更新

谢谢大家的帮助。我最终使用左连接,因为这对我来说是最快的,并产生了正确的结果。

DECLARE @Locations as Table(Name varchar(20));
DECLARE @Users as Table(Name varchar(20), Location varchar(20));

INSERT INTO @Users VALUES ('Chris', 'North')
INSERT INTO @Users VALUES ('John', 'North')
INSERT INTO @Users VALUES ('Jane', 'North-East')
INSERT INTO @Users VALUES ('Bryan', 'South')

INSERT INTO @Locations VALUES ('North')
INSERT INTO @Locations VALUES ('North-East')
INSERT INTO @Locations VALUES ('South')

SELECT 
    l.Name, 
    count(u.location)
FROM 
    @Locations l 
LEFT JOIN
     @Users u on l.Name = u.location and u.location in ('North', 'North-East')
group by 
l.Name;

3 个答案:

答案 0 :(得分:3)

我认为最简单的方法是使用条件聚合:

SELECT Location,
       SUM(CASE WHEN Location IN ('North', 'North-East') THEN 1 ELSE 0 END) as cnt
FROM Users u
GROUP BY Location;

或者,更好的是,如果您有位置表:

select l.location, count(u.location)
from locations l left join
     users u
     on l.location = u.location and
        u.location in ('North', 'North-East')
group by l.location;

答案 1 :(得分:1)

假设没有位置表,唯一的方法是执行DISTINCT和子选择

SELECT DISTINCT
    Location,
    (SELECT COUNT(*) FROM users AS U 
     WHERE U.Name = Users.Name
          AND Location = 'North' OR Location = 'North-East')
FROM Users
WHERE Location = 'North' OR Location = 'North-East'

此代码执行了大量的表扫描,并且可能会在生产环境中的大型表上运行时导致系统问题,此生产环境中的查询将每天运行多次。

答案 2 :(得分:1)

第三个选项,基于@GordonLinoff回答,但是给出了正确的结果如下。这使用子查询来获取不同的位置列表,并将其连接到users表。

select l.location, count(u.location)
from (SELECT DISTINCT Location FROM Users) l 
left join users u
     on l.location = u.location and
        u.location in ('North', 'North-East')
group by l.location