这两个mysql查询之间的区别?

Posted

技术标签:

【中文标题】这两个mysql查询之间的区别?【英文标题】:difference between these two mysql queries? 【发布时间】:2011-09-19 22:09:28 【问题描述】:

我认为这两个查询是相同的。但结果证明,第一个查询的约束从四个 AND 开始起作用,返回了许多带有左连接的错误行。第二个查询中的结果看起来是正确的。 谁能解释这两个查询之间有什么区别? 这个问题与this one 类似,但我100% 确定结果不同。

       SELECT uinfo.serial_number, uinfo.firmware, upd.objtype, upd.category
       FROM UnitInfo uinfo
       LEFT JOIN 
       UnitUpdateInfo upd
       ON uinfo.serial_number = upd.serial_number
       AND substring(uinfo.serial_number,1,2) NOT IN ('AB','CD','EF','GH')  
       AND substring(uinfo.serial_number,1,1) NOT LIKE 'M%'
       AND upd.objtype ='HEEN' 
       AND TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(uinfo.firmware, '-', -2), '-', 1)) LIKE '3.0%'   


       SELECT uinfo.serial_number, uinfo.firmware, upd.objtype, upd.category
       FROM UnitInfo uinfo
       LEFT JOIN 
       UnitUpdateInfo upd
       ON uinfo.serial_number = upd.serial_number
       WHERE substring(uinfo.serial_number,1,2) NOT IN ('AB','CD','EF','GH')  
       AND substring(uinfo.serial_number,1,1) NOT LIKE 'M%'
       AND upd.objtype ='HEEN' 
       AND TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(uinfo.firmware, '-', -2), '-', 1)) LIKE '3.0%'

[编辑] 第二个查询是一样的:

       SELECT uinfo.serial_number, uinfo.firmware, upd.objtype, upd.category
       FROM UnitInfo uinfo
       INNER JOIN 
       UnitUpdateInfo upd
       ON uinfo.serial_number = upd.serial_number
       WHERE substring(uinfo.serial_number,1,2) NOT IN ('AB','CD','EF','GH')  
       AND substring(uinfo.serial_number,1,1) NOT LIKE 'M%'
       AND upd.objtype ='HEEN' 
       AND TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(uinfo.firmware, '-', -2), '-', 1)) LIKE '3.0%'

【问题讨论】:

【参考方案1】:

只要LEFT JOIN 中的右侧表格具有比较的字段,例如WHERE 子句中的相等性,它实际上变成了 INNER JOIN - 在您的查询中,您强制 UnitUpdateInfoobjtype 字段为非 NULL => 连接必须成功。

第一个查询,将所有连接逻辑作为LEFT JOIN 的一部分,将包括第一个表中的所有行,这些行连接到第二个表中的那些行 - 对于无法连接的第二个表字段,空值.

第二个查询将包括第一个表中不连接到第二个表的那些行。

【讨论】:

我还是一头雾水。您的意思是第二个查询是内部联接,因为我对表 upd 有一些 where 条件,对吗?这就说得通了。但是为什么第一个查询中的“AND upd.objtype ='HEEN'”这样的条件不起作用? 第一个查询中LEFT JOIN 的条件指定连接右侧表中的行何时与左侧表中的行匹配。这种情况是“有效的”——只是不是你想要的。 对于第一个查询,upd.objtype='HEEN' 肯定不起作用,因为结果集中包含许多具有 NULL objtype 的行。恐怕我没有明白你的意思。简而言之,如果我的目的是获取 uinfo 中的所有行,upd 满足 uinfo 的三个条件,然后满足 upd 的一个条件,那么正确的查询是什么? 根据您的规范,您的第二个查询看起来像正确的查询 - 但 LEFT JOIN 被 INNER JOIN 替换。 太棒了,证实了这一点。对于第二个查询,在我拥有的所有 where 条件下,左连接结果与内连接相同。对于第一个查询,如果将连接更改为内连接,结果与第二个相同,但对于左连接,结果集要大得多。所有这些更多的行都来自 uinfo 的 NULL 行,不可能与 upd 连接,这使得那些条件不起作用。

以上是关于这两个mysql查询之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - 两个语句之间的区别

Mysql 子查询 - 需要在两个类似查询之间建立连接以计算邮政编码和邮政编码的出现次数

这些查询 MySQL 日期范围之间有啥区别

这三个 MySQL 查询有啥区别?

mysql中两个大表之间的连接查询

合并两个 MySQL 查询并获取两个邮政编码之间的距离