2008-10-15 70 views
1

我从MySQL SELECT询问涉及LEFT JOIN奇怪的结果,我不明白我对LEFT JOIN的理解是否是错误的,或者我是否看到一个真正奇怪的行为。MySQL LEFT JOIN SELECT不选择所有左侧记录?

我有一个多对一关系的两个表:对于table 1中的每个记录,table 2中有0个或更多记录。我想选择表1中的所有记录,并在列中计算表2中相关记录的数量。据我所知,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 | 
+------------+-----------------+ 

出现零计数的第一条记录,但忽略具有零计数的较晚记录。

我做错了什么,或者我只是不明白左连接应该做什么?

回答

6

你需要GROUP BY d.dateID。在你的两个案例中,s.DateIDNULLLEFT JOIN),并将它们组合在一起。

我想你也会发现这是无效的(ANSI)SQL,因为d.date不是GROUP BY的一部分,也不是集合操作的结果,不应该是SELECT ed。

2

我想你的意思是按d.dateId分组。

1

尝试通过s.dateID

去除GROUP
1

10-12和10-13的dateid由您分组在一起。由于它们是2空值,因此计数值被计算为0

0

用d.dateID替换GROUP BY s.dateID。

1

我不知道这是否是有效的MySQL,但你很可能使用以下语法而不是

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

通过使用使用条款作废,将来这个错误你没有获得两个dateID的保持对...的跟踪。

+0

它在MySQL中工作(只是测试它,并提供与其他答案相同的正确结果)。 – 2008-10-15 20:30:55