我有这个问题:
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)
那我为什么要这样写呢?它有什么优势?
答案 0 :(得分:4)
简而言之:
EXISTS
在找到第一个结果而不是获取所有匹配记录时返回(因此当有多个记录符合条件时效率更高)EXISTS
在语义上是正确的。1
,并且该列包含NULL
,FALSE
,0
等,MySQL将隐式转换它到FALSE
,这会导致错误的结果。EXISTS
实际上是由ANSI标准定义的,而第二种形式则不是。 (第二个查询可能在其他DBMS中失败)作为额外的注意事项,当您使用*
时,您也可以使用EXISTS
,因为它会检查是否存在匹配的记录,而不是值。
答案 1 :(得分:0)
如果子查询返回任何行,则EXISTS子查询为TRUE,NOT EXISTS子查询为FALSE。
当您使用... (SELECT 1 FROM t2 WHERE t2.post_id = :id LIMIT 1)
时,您要么在成功时返回1
,要么在NULL
上返回分别被视为True
或False
的内容。
使用Exists
更专业,因为:
传统上,EXISTS子查询以SELECT *开头,但它可以从SELECT 5或SELECT column1开始,或者任何东西。 MySQL忽略了这样一个子查询中的SELECT列表,所以没有区别。
最好的方法是返回True
或False
。