【问题标题】:Why should I use EXISTS() function in MySQL?为什么要在 MySQL 中使用 EXISTS() 函数?
【发布时间】:2016-05-25 13:53:47
【问题描述】:

我有这个问题:

SELECT * FROM mytable t1
  WHERE t1.id = :id AND
        EXISTS(SELECT 1 FROM t2 WHERE t2.post_id = :id)

当我删除 EXISTS() 函数时,我的代码仍然有效:

SELECT * FROM mytable t1
  WHERE t1.id = :id AND
        (SELECT 1 FROM t2 WHERE t2.post_id = :id LIMIT 1)

那我为什么要写这个?它有什么优势?

【问题讨论】:

  • Exists 在第一次匹配时返回。子查询检索所有匹配的记录。去阅读手册。
  • @Pred 感谢您的提示。但是我已经编辑了我的第二个查询,那么现在有什么不同吗?
  • ANSI SQL 合规性是原因之一。
  • 输入EXISTS 会痛,但LIMIT 1 不会? EXISTS 在语义上是正确的。您的第二个查询将在其他 DBMS 上失败,这只是一个不好的做法。如果您不小心没有使用 1 而是使用列名,并且匹配记录包含 NULL 或 0,MySQL 会将其强制转换为 FALSE,您的查询将提供错误结果。
  • 您的第二个查询,如SELECT * FROM mytable t1 WHERE t1.id = :id AND 1,这是一个正确的查询。因为1 评估为真

标签: mysql sql exists


【解决方案1】:

简而言之:

  • EXISTS 在找到第一个结果时返回,而不是获取所有匹配的记录(因此当有多个匹配条件的记录时效率更高)
  • EXISTS 在语义上是正确的。
  • 当第二个查询中有一个列名而不是1,并且该列包含NULLFALSE0等时,MySQL会隐式将其转换为FALSE,这导致错误的结果。
  • EXISTS 实际上是由 ANSI 标准定义的,而第二种形式不是。 (第二个查询可能在其他 DBMS 中失败)

额外说明一下,当您使用EXISTS 时,您也可以使用*,因为它会检查是否有匹配的记录,而不是值。

【讨论】:

    【解决方案2】:

    如果子查询返回任何行,EXISTS 子查询为 TRUE,NOT EXISTS 子查询为 FALSE。

    当您使用... (SELECT 1 FROM t2 WHERE t2.post_id = :id LIMIT 1) 时,您要么成功返回1,要么返回NULL,分别视为TrueFalse

    Exists 合作更专业,因为:

    传统上,EXISTS 子查询以 SELECT * 开头,但它可以以 SELECT 5 或 SELECT column1 或任何其他开头。 MySQL 会忽略此类子查询中的 SELECT 列表,因此没有区别。

    返回TrueFalse采用最佳方式。

    来自MySQL Dev site的参考

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 2015-09-22
      • 2014-03-07
      • 1970-01-01
      • 2020-11-25
      相关资源
      最近更新 更多