如何获得计数为零的组?


12

我将尝试从SQL Server数据库中的数据制作图形。我会在所有街道上都看到这条街上生活的用户数,即使计数为零。

为此,我尝试了以下查询:

Create table Streets(
  ID int IDENTITY  primary key,
  Name varchar(100)
);

create table users(
  ID int IDENTITY  primary key,
  Username varchar(100),
  StreetID int references Streets(id)
);

insert into streets values ('1st street'), ('2nd street'), ('3rd street'), 
                           ('4th street'), ('5th street');
insert into users values ('Pol', 1), ('Doortje', 1), ('Marc', 2), ('Bieke', 2), 
                         ('Paulien', 2), ('Fernand', 2), ('Pascal', 2), ('Boma', 3), 
                         ('Goedele', 3), ('Xavier', 4);

select s.name as street, count(s.name) as count 
from users u inner join streets s on u.streetid = s.id
group by s.name

它给了我这个输出:

|   | street     | count |
| - | ---------- | ----- |
| 1 | 1st street | 2     |
| 2 | 2nd street | 5     |
| 3 | 3rd street | 2     |
| 4 | 4th street | 1     |

问题在于没有用户居住的第五街不会出现在结果中。我可以使用SQL Server执行此操作吗?在这里,你有一个小提琴

更新:如果这样做right join,我将得到以下结果:

|   | street     | count |
| - | ---------- | ----- |
| 1 | 1st street | 2     |
| 2 | 2nd street | 5     |
| 3 | 3rd street | 2     |
| 4 | 4th street | 1     |
| 5 | 5th street | 1     | 

看到这个小提琴。


4
正如没有人解释的那样,为什么 查询不返回预期结果:由于聚合函数忽略NULL,因此必须从内部表(从外部表进行计数)开始计数一列,该列被定义为NOT NULL(以便能够区分数据中的NULL和外部联接创建的NULL)。最简单的方法是计算连接列:COUNT(u.streetid)
dnoeth '17

因为right joinright outer join是一样的东西。我确实在我的答案中添加了@ jpmc26建议的解释。
SqlWorldWide

Answers:


17

您的查询无法按预期工作的原因:

内部联接为您提供2个表的交集。在您的情况下,5th streetusers表中没有任何条目,这就是为什么join没有为此生成任何条目的原因。

外部联接(右侧或左侧)将给出内部联接的结果,此外,还将根据外部联接的类型(左侧或右侧)给出左侧或右侧表中的所有不合格记录。

在这种情况下,我将Street放在连接的左侧,并使用左外部连接,因为您希望结果集中的所有街道(甚至计数为零)。

将您的选择查询更改为此。

SELECT S.Name AS Street,
       Count(U.Username) AS COUNT
FROM Streets S
LEFT OUTER JOIN Users U ON U.Streetid = S.Id
GROUP BY S.Name

结果 在此处输入图片说明


1
对我来说,从count(*)更改为count(customer.id)-与上面显示的类似-造成了很大的不同。谢谢:)
Zeek

9

这是一种可能的方式。

select s.name as streets,
       (select count(*)
        from   users
        where  StreetID = s.id) cnt
from   streets s;

7

清理代码以在区分大小写的实例上工作...

CREATE TABLE Streets
(
    ID INT IDENTITY PRIMARY KEY,
    Name VARCHAR(100)
);

CREATE TABLE users
(
    ID INT IDENTITY PRIMARY KEY,
    Username VARCHAR(100),
    StreetID INT
        REFERENCES Streets ( ID )
);

INSERT INTO Streets
VALUES ( '1st street' ),
    ( '2nd street' ),
    ( '3rd street' ),
    ( '4th street' ),
    ( '5th street' );
INSERT INTO users
VALUES ( 'Pol', 1 ),
    ( 'Doortje', 1 ),
    ( 'Marc', 2 ),
    ( 'Bieke', 2 ),
    ( 'Paulien', 2 ),
    ( 'Fernand', 2 ),
    ( 'Pascal', 2 ),
    ( 'Boma', 3 ),
    ( 'Goedele', 3 ),
    ( 'Xavier', 4 );

COUNT与列名一起使用时,它会计算NOT NULL值。

我在RIGHT JOIN这里用安抚乔·奥布比什。

SELECT   s.Name AS street, COUNT(u.Username) AS count
FROM     users AS u
RIGHT JOIN Streets AS s
ON u.StreetID = s.ID
GROUP BY s.Name

结果:

street      count
1st street  2
2nd street  5
3rd street  2
4th street  1
5th street  0

0
  1. 通过街道ID获取计数
  2. 加入街道ID和街道ID
  3. 使用Coalsesce作为空值将导致

这是简短的查询:

select Name, coalesce( u.ct,0)ct FROM streets s left join (
select StreetID,count(*)ct from users group by StreetID)u on s.ID=u.StreetID

那就是左
联接
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.