<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>数据库 on My Blog</title>
    <link>http://localhost:1313/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/</link>
    <description>Recent content from My Blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    
    <managingEditor>3453434429@qq.com (ArenBase)</managingEditor>
    <webMaster>3453434429@qq.com (ArenBase)</webMaster>
    
    <copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright>
    
    <lastBuildDate>Mon, 11 May 2026 00:00:00 +0000</lastBuildDate>
    
    
    <atom:link href="http://localhost:1313/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/index.xml" rel="self" type="application/rss&#43;xml" />
    

    
    

    <item>
      <title>SQL 中 IN 与 EXISTS 的区别</title>
      <link>http://localhost:1313/post/sql-%E4%B8%AD-in-%E4%B8%8E-exists-%E7%9A%84%E5%8C%BA%E5%88%AB/</link>
      <pubDate>Mon, 11 May 2026 00:00:00 &#43;0000</pubDate>
      <author>3453434429@qq.com (ArenBase)</author>
      <guid>http://localhost:1313/post/sql-%E4%B8%AD-in-%E4%B8%8E-exists-%E7%9A%84%E5%8C%BA%E5%88%AB/</guid>
      <description>
        <![CDATA[<h1>SQL 中 IN 与 EXISTS 的区别</h1><p>作者：ArenBase（3453434429@qq.com）</p>
        
          <h1 id="sql-中-in-与-exists-的区别笔记含常见误区澄清">
<a class="header-anchor" href="#sql-%e4%b8%ad-in-%e4%b8%8e-exists-%e7%9a%84%e5%8c%ba%e5%88%ab%e7%ac%94%e8%ae%b0%e5%90%ab%e5%b8%b8%e8%a7%81%e8%af%af%e5%8c%ba%e6%be%84%e6%b8%85"></a>
SQL 中 IN 与 EXISTS 的区别笔记（含常见误区澄清）
</h1><blockquote>
<p>基于常见问题与易混淆点整理，重点标注容易出错和误导的地方。</p></blockquote>
<hr>
<h2 id="一核心区别速览">
<a class="header-anchor" href="#%e4%b8%80%e6%a0%b8%e5%bf%83%e5%8c%ba%e5%88%ab%e9%80%9f%e8%a7%88"></a>
一、核心区别速览
</h2><table>
  <thead>
      <tr>
          <th>维度</th>
          <th><code>IN</code></th>
          <th><code>EXISTS</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>语义</strong></td>
          <td>判断外层表达式的值是否<strong>存在于</strong>子查询返回的<strong>值列表</strong>中。</td>
          <td>判断子查询<strong>是否有行返回</strong>（存在性检查）。</td>
      </tr>
      <tr>
          <td><strong>子查询返回列数</strong></td>
          <td>通常<strong>只能返回一列</strong>；多列需使用<strong>行构造器</strong>且外层也要匹配。</td>
          <td><strong>可以返回任意列</strong>，甚至 <code>SELECT *</code>，返回值本身无关紧要。</td>
      </tr>
      <tr>
          <td><strong>对 <code>NULL</code> 的处理</strong></td>
          <td>⚠️ 容易出错：<code>NOT IN</code> 若子查询结果包含 <code>NULL</code>，整个查询<strong>返回空</strong>（不是报错）。</td>
          <td>✅ 安全：子查询的 <code>WHERE</code> 条件正常比较，不受子查询 <code>SELECT</code> 列中的 <code>NULL</code> 影响。</td>
      </tr>
      <tr>
          <td><strong>典型适用场景</strong></td>
          <td>子查询结果集<strong>小</strong>且<strong>确定无 <code>NULL</code></strong>；或者用于常量列表。</td>
          <td>相关子查询、可能遇 <code>NULL</code> 的场合、希望利用索引提前退出。</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="二详细对比与易混淆点澄清">
<a class="header-anchor" href="#%e4%ba%8c%e8%af%a6%e7%bb%86%e5%af%b9%e6%af%94%e4%b8%8e%e6%98%93%e6%b7%b7%e6%b7%86%e7%82%b9%e6%be%84%e6%b8%85"></a>
二、详细对比与易混淆点澄清
</h2><h3 id="1-子查询返回多列的问题">
<a class="header-anchor" href="#1-%e5%ad%90%e6%9f%a5%e8%af%a2%e8%bf%94%e5%9b%9e%e5%a4%9a%e5%88%97%e7%9a%84%e9%97%ae%e9%a2%98"></a>
1. 子查询返回多列的问题
</h3><ul>
<li><code>IN</code>：以下写法<strong>会报错</strong>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">WHERE</span><span class="w"> </span><span class="n">class_id</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">class</span><span class="p">)</span><span class="w">   </span><span class="c1">-- 错误：子查询返回多列
</span></span></span></code></pre></div>除非使用行构造器，且外层同样匹配：
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">WHERE</span><span class="w"> </span><span class="p">(</span><span class="n">class_id</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">)</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">class</span><span class="p">)</span><span class="w">   </span><span class="c1">-- 正确
</span></span></span></code></pre></div></li>
<li><code>EXISTS</code>：完全无此限制，<code>SELECT 1</code>、<code>SELECT *</code>、<code>SELECT id, name</code> 都可以。</li>
</ul>
<h3 id="2-null-的陷阱最容易出-bug">
<a class="header-anchor" href="#2-null-%e7%9a%84%e9%99%b7%e9%98%b1%e6%9c%80%e5%ae%b9%e6%98%93%e5%87%ba-bug"></a>
2. <code>NULL</code> 的陷阱（最容易出 bug）
</h3><h4 id="错误认知not-in-遇到-null-会报错">
<a class="header-anchor" href="#%e9%94%99%e8%af%af%e8%ae%a4%e7%9f%a5not-in-%e9%81%87%e5%88%b0-null-%e4%bc%9a%e6%8a%a5%e9%94%99"></a>
错误认知：“<code>NOT IN</code> 遇到 <code>NULL</code> 会报错”
</h4><p><strong>真相</strong>：不会报错，但查询<strong>静默返回空结果集</strong>，业务上极其隐蔽。</p>
        
        <hr><p>本文2026-05-11首发于<a href='http://localhost:1313/'>My Blog</a>，最后修改于2026-05-11</p>]]>
      </description>
      
        <category>SQL</category>
      
    </item>
    
  </channel>
</rss>
