MySQL 中exists与in及any的用法详解

MySQL 中exists与in及any的用法详解1 exists 对外表用 loop 逐条查询 每次查询都会查看 exists 的条件语句 当 exists 里的条件语句能够返回记录行时 无论记录行是多少 只要能返回 条件就为真 返回当前 loop 到的这条记录 反之如果 exists 里的条件语句不能返回记录行 条件为假 则当前 loop 到的这条记录被丢弃 exists 的条件就像一个 bool 条件 当能返回结果集则为 true 不能返回结果集则为 false 语

【1】exists

对外表用循环逐条查询,每次循环查询都会判断exists的条件语句。

当 exists里的条件语句能够返回记录行时(无论记录行是多少,只要能返回),条件就为真 , 返回当前loop到的这条记录。反之如果exists里的条件语句不能返回记录行,条件为假,则当前loop到的这条记录被丢弃。

将主查询的数据放到子查询中做条件验证,根据验证结果(true or false)来决定主查询的数据结果是否得以保留。

exists的条件就像一个boolean条件,当能返回结果集则为1,不能返回结果集则为 0。

语法格式如下:

select * from tables_name where [not] exists(select..); 

示例如下:

select * from p_user_2 where EXISTS(select * from p_user where id=12) 

如果p_user表中有id为12的记录,那么将返回所有p_user_2表中的记录;否则,返回记录为空。如果是not exists,则与上述相反。

总的来说,如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件 。所以子查询表大于外表的时候适合用exists,否则适合用in。


【2】in

语法格式如下:

select * from A where column in (select column from B); 

需要说明的是,where中,column为A的某一列,in 所对应的子查询语句返回为一列多行结果集。

注意,in所对应的select语句返回的结果一定是一列!可以为多行。

示例如下:

select * from p_user_2 where id [not] in (select id from p_user ) 

查询id在p_user表id集合的p_user_2的记录。not in则相反。


【3】exists与in的关系

mysql中in和exists区别

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询(所以子查询为大表适合exists)。

一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的,这个是要区分环境的。

  • 如果查询的两个表大小相当,那么用in和exists差别不大。
  • 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
  • not in 和not exists:如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

当然经过sql改变,二者是可以达到同一个目标的:

select * from p_user_2 where id [not] in (select id from p_user ); select * from p_user_2 where [not] EXISTS (select id from p_user where id = p_user_2.id ) 

例如:表A(小表),表B(大表)

① 子查询表为表B

如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in

select * from A where cc in (select cc from B) //效率低,用到了A表上cc列的索引; select * from A where exists(select cc from B where cc=A.cc) //效率高,用到了B表上cc列的索引。  

② 子查询表为表A

select * from B where cc in (select cc from A) //效率高,用到了B表上cc列的索引; select * from B where exists(select cc from A where cc=B.cc) //效率低,用到了A表上cc列的索引。 

这里也涉及到一个优化原则:小表驱动大表。子查询表大的时候用exists,子查询表小的时候用in。

【4】any/some/all

① any,in,some,all分别是子查询关键词之一

any 可以与=、>、>=、<、<=、<>结合起来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的任意一个数据。

all可以与=、>、>=、<、<=、<>结合是来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的其中的所有数据。

它们进行子查询的语法如下:

operand comparison_operator any (subquery); operand in (subquery); operand coparison_operator some (subquery); operand comparison_operator all (subquery); 

any,all关键字必须与一个比较操作符一起使用。

② any关键词

可以理解为“对于子查询返回的列中的任一数值,如果比较结果为true,则返回true”。

例如:

select age from t_user where age > any (select age from t_user_copy); 

假设表t_user 中有一行包含(10),t_user_copy包含(21,14,6),则表达式为true;如果t_user_copy包含(20,10),或者表t_user_copy为空表,则表达式为false。如果表t_user_copy包含(null,null,null),则表达式为unkonwn。


all的意思是“对于子查询返回的列中的所有值,如果比较结果为true,则返回true”

例如:

select age from t_user where age > all (select age from t_user_copy); 

假设表t_user 中有一行包含(10)。如果表t_user_copy包含(-5,0,+5),则表达式为true,因为10比t_user_copy中的查出的所有三个值大。如果表t_user_copy包含(12,6,null,-100),则表达式为false,因为t_user_copy中有一个值12大于10。如果表t_user_copy包含(0,null,1),则表达式为unknown。如果t_user_copy为空表,则结果为true。


③ not in /in

not in 是 “<>all”的别名,用法相同。

语句in 与“=any”是相同的。

例如:

select s1 from t1 where s1 = any (select s1 from t2); select s1 from t1 where s1 in (select s1 from t2); 

语句some是any的别名,用法相同。

例如:

select s1 from t1 where s1 <> any (select s1 from t2); select s1 from t1 where s1 <> some (select s1 from t2); 

在上述查询中some理解上就容易了“表t1中有部分s1与t2表中的s1不相等”,这种语句用any理解就有错了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211484.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午10:19
下一篇 2026年3月18日 下午10:19


相关推荐

  • BootstrapValidator中文文档手册

    BootstrapValidator中文文档手册BootstrapVal 0 5 3 下载地址 https download csdn net download 目前支持 4 种大的校验方式 分别是 Input 针对 input textarea select 控件 CompareValid AjaxValidato RegexValidat FunctionVali

    2026年3月17日
    2
  • 如何配置android的adb环境变量(jre环境变量配置)

    一、安装完AndroidStudio后会默认在其下面安装SDK1.找到文件sdk下的tools和platform-tools,并复制其路径2.打开环境变量配置3.新建系统变量,命名为Android_ADB,并将上述两个路径分别导入,中间用;隔开4.打开path变量,输入%Android_ADB%5.打开终端,输入adbversion,出现帮助信息,完成配置。二

    2022年4月9日
    47
  • cad转dxf格式文件太大,将CAD图纸文件进行转换成低版本DXF格式如何进行?

    cad转dxf格式文件太大,将CAD图纸文件进行转换成低版本DXF格式如何进行?将 CAD 图纸文件进行转换成低版本 DXF 格式如何进行 CAD 图纸文件在绘制时候会有不同的版本但是在进行查看的时候会由于图纸的版本问题而无法将图纸文件进行打开 这个时候就需要进行的操作就是将其进行版本间的转换了 具体应该怎么样进行操作 接下来小编就要来教大家的就是将 CAD 图纸文件进行转换成低版本 DXF 格式如何进行的全部操作步骤 希望以下能够帮助到你们 步骤一 首先要打开电脑 打开浏览器在搜索框中输入

    2025年7月12日
    4
  • 1.零基础如何学习Web安全渗透测试?[通俗易懂]

    1.零基础如何学习Web安全渗透测试?[通俗易懂]零基础如何学习Web安全渗透测试?这可能是史上最详细的自学路线图!转载于拼客学院陈鑫杰拼客院长陈鑫杰(若有侵权,请联系邮件751493745@qq.com,我会及时删除)(转载链接:https://mp.weixin.qq.com/s/SlG_tWSEXapMeOezfBrnww)…

    2025年6月13日
    4
  • ElasticSearch搜索引擎常见面试题总结

    ElasticSearch搜索引擎常见面试题总结

    2021年10月5日
    42
  • 《算法设计与分析》期末不挂科的原因_算法设计与分析重点

    《算法设计与分析》期末不挂科的原因_算法设计与分析重点考前知识点整理算法分析基础算法的定义算法正确性算法的性质程序的定义程序与算法的区别算法设计和分析的步骤复杂度分析算法的时间复杂性算法渐近复杂性渐近分析的记号渐近上界记号渐近下界记号非紧上界记号非紧下界记号紧渐近界记号意义算法分析中常见的复杂性函数我们学校开设的这门课,过于理论,实践太少,考试不会太难,一起学习,一起不挂科!但是算法平时一定要练哦!加油!算法分析基础算法的定义算法是指解决问题的一种方法或一个过程。算法是若干指令的有穷序列。算法正确性对每一个输入实例算法都能终止,并给出

    2022年10月6日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号