You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Adventure Works 2017下两条SQL Server查询结果不一致?

两个SQL查询结果差异原因解释

使用的数据库为Adventure Works 2017,两条查询结果不同的核心原因是JOIN的执行顺序与作用范围被括号改变,逻辑完全不同:

查询1执行逻辑

select 
    c.CustomerID, c.FirstName, c.EmailAddress,
    a.AddressID as addrId, addr.AddressLine1 as address 
from
    [AdventureWorksLT2017].[SalesLT].[Customer] c 
left join 
    (
        [AdventureWorksLT2017].[SalesLT].[CustomerAddress] a 
        inner join 
            [AdventureWorksLT2017].[SalesLT].[Address] addr 
        on addr.AddressID = a.AddressID
    ) 
    on c.CustomerID=a.CustomerID
where 
    c.EmailAddress = 'orlando0@adventure-works.com';
  • 首先执行括号内的INNER JOIN:先对CustomerAddress和Address做内连接,只有同时存在两张表的关联记录才会被保留,过滤掉所有没有对应地址的客户地址关联记录。
  • 再将上述得到的关联地址结果集,和Customer表做LEFT JOIN:符合WHERE条件的客户记录一定会被保留,不管有没有匹配到关联地址结果,没有匹配到的地址相关字段返回NULL。

查询2执行逻辑

select 
    c.CustomerID, c.FirstName, c.EmailAddress,
    a.AddressID as addrId, addr.AddressLine1 as address 
from
    [AdventureWorksLT2017].[SalesLT].[Customer] c 
left join 
    [AdventureWorksLT2017].[SalesLT].[CustomerAddress] a 
    on a.CustomerID = c.CustomerID 
inner join  
    [AdventureWorksLT2017].[SalesLT].[Address] addr 
    on addr.AddressID = a.AddressID
where 
    c.EmailAddress = 'orlando0@adventure-works.com';
  • 第一步先执行Customer和CustomerAddress的LEFT JOIN:符合WHERE条件的客户记录先被保留,没有关联的客户地址记录时,a.AddressID等字段返回NULL。
  • 第二步将上述结果集和Address做INNER JOIN:内连接要求a.AddressID = addr.AddressID,上一步结果中所有a.AddressID为NULL、或者a.AddressID在Address表中找不到匹配的记录都会被直接过滤,最终结果仅保留同时有客户地址关联、且地址记录存在的客户。

差异总结

如果查询的客户没有关联的CustomerAddress记录,或者关联的地址不存在于Address表中:

  • 查询1会返回该客户的基础信息,地址相关字段为NULL
  • 查询2会直接过滤掉该客户,结果中无对应记录

内容的提问来源于stack exchange,提问作者Saurav Sehgal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 00:24:03