วิธีรับกลุ่มที่การนับเป็นศูนย์ได้อย่างไร


12

ฉันจะพยายามสร้างกราฟจากข้อมูลจากฐานข้อมูลเซิร์ฟเวอร์ SQL ของฉัน ฉันจะมีถนนทุกเส้นที่มีจำนวนผู้ใช้ที่อาศัยอยู่บนถนนเส้นนี้แม้จำนวนนั้นจะเป็นศูนย์

สำหรับสิ่งนี้ฉันได้ลองใช้แบบสอบถามนี้:

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     |

ปัญหาคือถนนสายที่ 5 ซึ่งไม่มีผู้ใช้อาศัยอยู่จะไม่ปรากฏในผลลัพธ์ ฉันสามารถทำสิ่งนี้กับเซิร์ฟเวอร์ SQL ได้หรือไม่ ที่นี่คุณมีไวโอลิน

อัปเดต:ถ้าฉันทำ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 ที่สร้างโดย Outer Join) วิธีที่ง่ายที่สุดคือการนับคอลัมน์เข้าร่วม:COUNT(u.streetid)
dnoeth

เพราะright joinและright outer joinเป็นสิ่งเดียวกัน ฉันเพิ่มคำอธิบายลงในคำตอบตามที่ @ jpmc26 แนะนำ
SqlWorldWide

คำตอบ:


17

สาเหตุที่คิวรีของคุณไม่ทำงานตามที่ต้องการ:

Inner join ช่วยให้คุณมีจุดตัดสองตาราง ในกรณีของคุณไม่มีรายการสำหรับ5th streetในตารางผู้ใช้ของคุณและนั่นคือเหตุผลที่การเข้าร่วมไม่ได้สร้างรายการใด ๆ สำหรับสิ่งนั้น

การรวมภายนอก (ขวาหรือซ้าย) จะให้ผลลัพธ์ของการรวมภายในและนอกเหนือจากระเบียนที่ไม่ผ่านการคัดเลือกทั้งหมดจากตารางซ้ายหรือขวาขึ้นอยู่กับประเภท (ซ้ายหรือขวา) ของการรวมภายนอก

ในกรณีนี้ฉันวาง 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ที่นี่เพื่อเอาใจ 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

ผล:

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

0
  1. รับการนับตามรหัสถนน
  2. เข้าร่วม ID สตรีทด้วย ID จากถนน
  3. ใช้ Coalsesce เป็นค่า Null จะส่งผล

นี่คือแบบสอบถามสั้น ๆ :

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

นั่นคือด้วยการเข้าร่วมซ้าย
rakesh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.