帮助将子查询转换为带连接的查询
Posted
技术标签:
【中文标题】帮助将子查询转换为带连接的查询【英文标题】:Help converting subquery to query with joins 【发布时间】:2010-03-13 12:53:20 【问题描述】:我被一个带有连接的查询卡住了。客户端的站点正在运行 mysql4,因此子查询不是一个选项。我使用连接重写的尝试并不顺利。
我需要选择承包商表中列出的所有承包商,这些承包商不在contractors2label 表中,并且具有给定的标签 ID 和县 ID。然而,它们可能会列在 带有其他标签和县 ID 的contractors2label。
表:承包商
cID(主要,自动编号) 公司 (varchar) ...等等...
表:contractors2label
cID 标签ID 县ID psID
这个带有子查询的查询有效:
SELECT company, contractors.cID
FROM contractors
WHERE contractors.complete = 1
AND contractors.archived = 0
AND contractors.cID NOT IN (
SELECT contractors2label.cID FROM contractors2label
WHERE labelID <> 1 AND countyID <> 1
)
我认为这个带有连接的查询是等价的,但它没有返回任何结果。手动扫描数据显示我应该得到 34 行,这就是上面的子查询返回的内容。
SELECT company, contractors.cID
FROM contractors
LEFT OUTER JOIN contractors2label ON contractors.cID = contractors2label.cID
WHERE contractors.complete = 1
AND contractors.archived = 0
AND contractors2label.labelID <> 1
AND contractors2label.countyID <> 1
AND contractors2label.cID IS NULL
【问题讨论】:
+1 表示是新手,并设法提供格式正确的问题,并很好地描述了您的问题,包括示例代码 :) 【参考方案1】:在做LEFT JOIN
时,需要将JOIN
的所有条件放入ON
子句中。
在您的示例中,您会为不存在的左连接列获得 NULL
,但您随后将它们再次与无效的值 (<> 1
) 进行比较。
SELECT c.company, c.cID
FROM contractors c
LEFT JOIN contractors2label c2
ON ( c2.cID = c.cID AND c2.labelID <> 1 AND c2.countyID <> 1 )
WHERE c.complete = 1
AND c.archived = 0
AND c2.cID IS NULL
顺便说一句:使用别名(例如我的示例中的 c
)可以让您更轻松地阅读和编写查询。
【讨论】:
好吧,我不应该跳得这么快。当我将它插入我的应用程序时,它实际上不起作用。 @Tim:你能描述一下你面临的问题吗? 我的错……我的逻辑是落后的。如果我更改为 ON ( c2.cID = c.cID AND c2.labelID = 1 AND c2.countyID = 1 ),您的查询将为我提供我需要的东西,顺便说一句,我认为下面@Nick 的答案也可以使用 to = 改变。 @Tim:我同意,尼克斯的回答也应该有效。我认为你应该投票 - 如果你愿意,你也可以投票给我的 ;-) 我刚刚在这里创建了一个帐户,以便对答案进行投票。谢谢你们!【参考方案2】:当您使用 LEFT
联接的表中的列限制 where 子句时,您实际上是在删除联接的 LEFT OUTER
部分,因为您正在过滤必须存在的列。试试这个:
SELECT company, contractors.cID
FROM contractors
LEFT OUTER JOIN contractors2label
ON (contractors.cID = contractors2label.cID
AND contractors2label.labelID <> 1
AND contractors2label.countyID <> 1)
WHERE contractors.complete = 1
AND contractors.archived = 0
AND contractors2label.cID IS NULL
这将限制作为连接的一部分,因此空值仍然可以在更大的查询中使用。
【讨论】:
以上是关于帮助将子查询转换为带连接的查询的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 6,MYSQL - 如何使用 Laravel Querybuilder 或 Model Eloquent 将子查询与 GroupBY 左连接?