카운트가 0 인 그룹을 얻는 방법?


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     |

문제는 사용자가없는 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을 구분합니다. 가장 쉬운 방법은 조인 열을 계산하는 것입니다.COUNT(u.streetid)
dnoeth

때문에 right joinright outer join같은 것들입니다. @ jpmc26에서 제안한대로 답변에 설명을 추가했습니다.
SqlWorldWide

답변:


17

쿼리가 의도 한대로 작동하지 않은 이유 :

내부 조인은 두 테이블의 교차점을 제공합니다. 귀하의 경우, 5th streetusers 테이블에 항목이 없었기 때문에 join은 해당 항목을 생성하지 않습니다.

외부 조인 (오른쪽 또는 왼쪽)은 외부 조인의 유형 (왼쪽 또는 오른쪽)에 따라 내부 조인의 결과와 왼쪽 또는 오른쪽 테이블의 모든 규정되지 않은 레코드를 제공합니다.

이 경우 조인의 왼쪽에 Street를 배치하고 결과 집합의 모든 거리 (카운트는 0 임)를 원할 때 왼쪽 외부 조인을 사용했습니다.

선택 쿼리를 이것으로 변경하십시오.

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 JOINJoe 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. 거리 ID로 개수를 가져옵니다
  2. 거리에서 아이디로 거리 아이디에 가입
  3. Coalesce를 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.