Làm thế nào để có được một nhóm trong đó số đếm bằng không?


12

Tôi sẽ cố gắng tạo một biểu đồ từ dữ liệu từ cơ sở dữ liệu máy chủ SQL của tôi. Tôi sẽ có tất cả các đường phố với số lượng người dùng đang sống ở đường này thậm chí số lượng bằng không.

Đối với điều này, tôi đã thử truy vấn này:

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

Và nó mang lại cho tôi đầu ra này:

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

Vấn đề là đường thứ 5, nơi không có người dùng sống, không xuất hiện trên kết quả. Tôi có thể làm điều này với máy chủ SQL không? Ở đây bạn đã có một câu đố

Cập nhật: Nếu tôi làm right join, tôi đã nhận được kết quả này:

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

Xem câu đố này.


4
Như không ai giải thích lý do tại sao truy vấn của bạn không trả về kết quả mong đợi: Vì hàm tổng hợp bỏ qua NULL, bạn phải đếm một cột từ bảng bên trong (bạn đã đếm từ bảng bên ngoài) được xác định là KHÔNG NULL (để có thể phân biệt giữa các NULL trong dữ liệu và NULL được tạo bởi Outer Join). Cách dễ nhất là đếm cột tham gia:COUNT(u.streetid)
vào

Bởi vì right joinright outer joinlà những thứ giống nhau. Tôi đã thêm một lời giải thích trong câu trả lời của mình theo đề xuất của @ jpmc26.
SqlWorldWide

Câu trả lời:


17

Lý do truy vấn của bạn không hoạt động như dự định:

Tham gia bên trong cung cấp cho bạn giao điểm của 2 bảng. Trong trường hợp của bạn, không có mục nào 5th streettrong bảng người dùng của bạn và đó là lý do tại sao tham gia không tạo ra bất kỳ mục nào cho điều đó.

Tham gia ngoài (phải hoặc trái) sẽ cho kết quả của tham gia bên trong và ngoài ra tất cả các bản ghi không đủ điều kiện từ bảng bên trái hoặc bên phải tùy thuộc vào loại (bên trái hoặc bên phải) của tham gia bên ngoài.

Trong trường hợp này, tôi đặt Street ở bên trái của phép nối và sử dụng phép nối ngoài bên trái như bạn muốn tất cả các đường (số chẵn là 0) trong tập kết quả của bạn.

Thay đổi truy vấn chọn của bạn để này.

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

Kết quả nhập mô tả hình ảnh ở đây


1
Đối với tôi, việc thay đổi từ đếm (*) sang đếm (customer.id) - tương tự như hiển thị ở trên - đã tạo ra sự khác biệt quan trọng. Cảm ơn :)
Zeek

9

Đây là một cách có thể.

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

3
Chọn cùng một bảng một lần nữa trong mệnh đề chọn, điều đó có gây ra vấn đề hiệu năng nào không? (+1)
Saqib

7

Làm sạch mã để làm việc trong trường hợp nhạy cảm trường hợp ...

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 );

Khi bạn sử dụng COUNTvới một tên cột, nó sẽ đếm NOT NULLcác giá trị.

Tôi đang sử dụng RIGHT JOINở đây để xoa dịu Joe Obbish.

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

Các kết quả:

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

0
  1. Lấy số đếm theo id đường phố
  2. tham gia id đường phố với id từ đường phố
  3. Sử dụng Coalsesce làm giá trị null sẽ dẫn đến

Đây là truy vấn ngắn:

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

Đó là với sự tham gia trái
rakesh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.