MySQL左连接并没有给我我所期望的

时间:2014-05-29 15:26:50

标签: mysql left-join

我想要一些关于左连接语句的帮助,这些语句没有做我可能错误的认为它应该做的事情。

有两个表:

CD:

CREATE TABLE `cd` (
  `itemID` int(11) NOT NULL AUTO_INCREMENT,
  `title` text NOT NULL,
  `artist` text NOT NULL,
  `genre` text NOT NULL,
  `tracks` int(11) NOT NULL,
  PRIMARY KEY (`itemID`)
)

贷款

CREATE TABLE `loans` (
  `itemID` int(11) NOT NULL,
  `itemType` varchar(20) NOT NULL,
  `userID` int(11) NOT NULL,
  `dueDate` date NOT NULL,
  PRIMARY KEY (`itemID`,`itemType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我希望选择所有不使用左连接的贷款,然后选择dueDate为空

select 
    t.itemID, 
    t.artist as first, 
    t. title as second, 
    (select AVG(rating) from ac9039.ratings where itemType = 'cd' and itemId = t.itemID) as `rating avarage`, 
    (select COUNT(rating) from ac9039.ratings where itemType = 'cd' and itemId = t.itemID) as `number of ratings` 
from 
    cd t left join loans l 
    on t.itemID = l.itemID 
where l.itemType = 'cd' and l.dueDate is null;

但是这个会返回一个空表,即使cd中有很多行,而itemID也不在贷款中

现在我理解左连接应该保留右边并用左值填充lefthandside的列 但这似乎并非如此,能不能过去启发我吗?

1 个答案:

答案 0 :(得分:1)

您的WHERE条件会导致错误。如果L.ItemType = 'cd'为真,L.DueDate IS NULL将始终返回false。 (您的所有字段均为NOT NULL,因此如果没有匹配的记录,则DueDate只能是NULL,但在这种情况下,ItemType字段将为{{1}也是)。

另一点是您的查询在语义上不正确。您正试图从NULL表中获取记录,其中cd表不包含任何具有dueDates的行。 第二个表充当条件,因此它应该转到loans条件。

考虑使用WHERE语句来实现您的目标:

EXISTS

根据您的数据模型,您必须向子查询添加另一个条件,以过滤掉那些过时的记录(dueDate早于当前时间)

如果您不删除过期的贷款记录,则会出现这种情况。

SELECT 
    t.itemID, 
    t.artist as first, 
    t. title as second, 
    (select AVG(rating) from ac9039.ratings where itemType = 'cd' and itemId = t.itemID) as `rating avarage`, 
    (select COUNT(rating) from ac9039.ratings where itemType = 'cd' and itemId = t.itemID) as `number of ratings` 
FROM 
    cd t
WHERE
    NOT EXISTS (SELECT 1 FROM loans l WHERE t.itemID = l.itemID AND L.itemType = 'cd')