2008-10-15 5 views
1

LEFT JOIN과 관련된 MySQL SELECT 쿼리에서 이상한 결과가 나옵니다. 내 이해가 LEFT JOIN인지 여부 또는 실제로 이상한 동작인지 여부를 이해할 수 없습니다.MySQL LEFT JOIN SELECT는 모든 왼쪽 레코드를 선택하지 않습니까?

다 대일 관계가있는 두 개의 테이블이 있습니다. table 1의 모든 레코드에 대해 table 2에 0 개 이상의 레코드가 있습니다. 테이블 2의 관련 레코드 수를 계산하는 열과 함께 테이블 1의 모든 레코드를 선택하고 싶습니다. 이해할 수 있듯이 LEFT JOIN은 항상 LEFT 쪽의 모든 레코드를 반환해야합니다.

는 여기에 문제를 전시 테스트 데이터베이스입니다 :

CREATE DATABASE Test; 
USE Test; 

CREATE TABLE Dates (
    dateID INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    date DATE NOT NULL, 
    UNIQUE KEY (dateID) 
) TYPE=MyISAM; 


CREATE TABLE Slots (
    slotID INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    dateID INT UNSIGNED NOT NULL, 
    UNIQUE KEY (slotID) 
) TYPE=MyISAM; 

INSERT INTO Dates (date) VALUES ('2008-10-12'),('2008-10-13'),('2008-10-14'); 
INSERT INTO Slots (dateID) VALUES (3); 

날짜 테이블이 세 가지 기록하고, 슬롯 1가 - 그리고 날짜에서 세 번째 기록에 해당 레코드 점을.

나는 다음과 같은 쿼리를한다면 ..

SELECT d.date, count(s.slotID) FROM Dates AS d LEFT JOIN Slots AS s ON s.dateID=d.dateID GROUP BY s.dateID; 

.. 난이 3 개 행이 테이블을 볼 것으로 예상 - 0의 수 두, 그리고 1의 개수 그러나 내가 하나 실제로 볼 수 있습니다 :

+------------+-----------------+ 
| date  | count(s.slotID) | 
+------------+-----------------+ 
| 2008-10-12 |    0 | 
| 2008-10-14 |    1 | 
+------------+-----------------+ 

제로 카운트가있는 첫 번째 레코드가 나타나지만 카운트가 0 인 이후 레코드는 무시됩니다.

잘못된 것이 있습니까? 아니면 LEFT JOIN이해야 할 일을 이해하지 못합니까?

답변

6

GROUP BY d.dateID이 필요합니다. 두 경우에 s.DateIDNULL (LEFT JOIN)이며이 둘은 함께 결합됩니다.

d.date가 GROUP BY 또는 집계 연산의 결과가 아니며 SELECT이 될 수 없기 때문에 이것이 유효하지 않은 (ANSI) SQL이라는 것을 알게 될 것입니다.

2

d.dateId별로 그룹화 하시리라 생각합니다.

1

GROUP BY s.dateID를 삭제 해보십시오.

1

10-12 및 10-13의 dateid는 함께 그룹화됩니다. 2 개의 널 (NULL) 값이므로 계수는 0으로 평가됩니다.

0

은 GROUP BY s.dateID를 d.dateID로 바꿉니다.

1

이 MySQL의에서 유효하지만 당신은 아마 두 dateID 년대를하지 않는 USING 절을 사용하여 다음과 같은 구문 대신

SELECT date, count(slotID) as slotCount 
FROM Dates LEFT OUTER JOIN Slots USING (dateID) 
GROUP BY (date) 

를 사용하여 앞으로이 실수를 무효화 할 수 있다면 나도 몰라 추적 할 수 있습니다.

+0

이것은 MySQL에서 작동합니다 (테스트 한 결과와 다른 결과와 똑같은 결과가 나타납니다). –