我想要一些关于左连接语句的帮助,这些语句没有做我可能错误的认为它应该做的事情。
有两个表:
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的列 但这似乎并非如此,能不能过去启发我吗?
答案 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')