mysql子查询行比较逻辑

Posted

技术标签:

【中文标题】mysql子查询行比较逻辑【英文标题】:mysql subquery row comparision logic 【发布时间】:2021-10-17 15:44:08 【问题描述】:

我对子查询逻辑有疑问。据我了解,sql总是先解析子查询,然后再解析异常查询。但是,官方文档中的示例不支持。

链接来自mysql官方文档

https://dev.mysql.com/doc/refman/8.0/en/subqueries.html

Here is another example, which again is impossible with a join 
because it involves aggregating for one of the tables. 
It finds all rows in table t1 containing a value that occurs twice in a given column:

SELECT * FROM t1 AS t
  WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);

据我了解,当sql解析子查询时,会发现

(SELECT COUNT(*) FROM t1 WHERE t1.id = t.id)

根据表返回标量。然后当它与 2 比较时

它要么返回 t1 中的所有行,要么什么都不返回,因为这是一个简单的真假问题。

显然它不喜欢什么办公文件讨论 .根据官方文档,它更像是从 t1 表中逐行检查,与标量 2 进行比较,并一直循环整个表直到结束。

为什么逻辑是这样的?我很难理解其中的逻辑。 任何未来的解释都会有所帮助。

【问题讨论】:

【参考方案1】:

没有难度。

这取决于您返回的行数,因为它会检查 t1 的每一行并比较表中是否有 2 行具有该值。列克你可以看这里https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=d70942c0321f9310c3b89dbc9435b418

(SELECT COUNT(*) FROM t1 WHERE t1.id = t.id)

重新运行 1 个值(1 列 1 行)例如 3,它与您的 2 进行比较 =

只要子查询只返回 1 个值,你就可以用 = 将其与奇异值进行比较

对于结果集中的多行,您需要IN

喜欢

SELECT * FROM t1 AS t
  WHERE cis IN (SELECT t1.id FROM t1 WHERE t1.id = t.id);

当然你可以比较多列(如果你有多行,你也需要ÌN

SELECT * FROM t1 AS t
  WHERE (2,2) = (SELECT COUNT(*),SUM(abc = 'test') FROM t1 WHERE t1.id = t.id);

【讨论】:

谢谢。我明白。我感到困惑的是逻辑。 (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id) 应该只返回 1 列 1 行吧?在这种情况下,它无法达到使该行存在 2 次的目的。 不,count 是返回一个值的命令,与没有它时获得的行数无关, 如果是这样,子查询将只返回 1 个值,具体取决于表。所以当比较 2 = 值时,它要么返回所有 t1 表,要么什么都不返回,对吧? 2 = 1 是布尔值,会返回 0 但这与子查询无关 我不确定我是否关注你。如果我的理解正确,逻辑如下:子查询返回 1 个标量值——与 2---- 外部查询的比较---如果为真,则返回所有表,如果为假,则无返回

以上是关于mysql子查询行比较逻辑的主要内容,如果未能解决你的问题,请参考以下文章

MySQL子查询(SubQuery)

子查询事务python操作mysql索引

mysql 数据操作 子查询 带比较运算符的子查询

Mysql第八期 子查询

MySQL 的子查询和left join的比较,啥时候用子查询效率高,啥时候用left join效率高?

MySQL比较运算符的子查询