繁体   English   中英

帮助将子查询转换为带连接的查询

[英]Help converting subquery to query with joins

我坚持使用连接查询。 客户端的站点正在运行mysql4,因此子查询不是一个选项。 我尝试使用连接重写不太顺利。

我需要选择承包商表中列出的所有承包商,这些承包商不在承包商2标签表中,并且具有给定的标签ID和县ID。 然而,它们可能会在承包商2标签中列出其他标签和县ID。

表:承包商

cID(主要,自动编号)
公司(varchar)
...等等...

表:承包商2标签

CID
labelID
countyID
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

执行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 )可以更轻松地读取和编写查询。

当您使用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

这将限制作为连接的一部分,因此仍可以在较大的查询中使用null。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM