首页 > 解决方案 > JOIN 查询,SQL Server 正在删除我的第一个表的一些行

问题描述

我有两张桌子customer_detailsaddress_details. 我想显示带有相应地址的客户详细信息,所以我使用的是LEFT JOIN,但是当我执行此查询时,SQL Server 会删除street_nocustomer_details 表与 address_detials 表中的 street_no 不匹配的行,并仅显示 ` customer_details 的 street_no' = address_details 表的 street_no。我需要显示一个完整的 customer_details 表,如果 street_no 不匹配,它应该显示空字符串或任何东西。我在我的 SQL 连接中做错了什么吗?

customer_details

case_id customer_name  mob_no       street_no
-------------------------------------------------
 1           John      242342343    4324234234234
 1           Rohan     343233333    43332
 1           Ankit     234234233    2342332423433
 1           Suresh    234234324    2342342342342
 1           Ranjeet   343424323    32233
 1           Ramu      234234333    2342342342343

address_details

 s_no   streen_no       address        city    case_id
 ------------------------------------------------------
  1     4324234234234   Roni road      Delhi    1
  2     2342332423433   Natan street   Lucknow  1
  3     2342342342342   Koliko road    Herdoi   1   

SQL JOIN 查询:

select  
    a.*, b.address 
from 
    customer_details  a 
left join 
    address_details b on a.street_no = b.street_no 
where 
    b.case_id = 1 

标签: sqlsql-serverdatabaseouter-join

解决方案


既然你已经很清楚了used b.case_id=1,我将解释它为什么过滤:

LEFT JOIN 本身返回一些包含b结果集中表的所有 NULL 值的行,这是您想要和期望的。

但是通过使用WHERE b.case_id=1,表中包含 NULL 值的行b会被过滤掉,因为它们都不符合条件(所有这些行都有b.case_id=NULL,所以它们不匹配)。

改为使用 可能会起作用WHERE a.case_id=1,但我们不知道匹配行的值是否a.case_id并且b.case_id总是相同(它们可能不是;如果它们总是相同,那么我们只是确定了潜在的冗余)。

有两种方法可以肯定地解决这个问题。

(1) 移入b.case_id = 1左连接条件:

left join address_details b on a.street_no = b.street_no and b.case_id = 1

(2) 保留b.case_id = 1在 WHERE 中,但也允许 NULLED-outb值:

left join address_details b on a.street_no = b.street_no 
where b.case_id = 1
or    b.street_no IS NULL

就我个人而言,我会选择(1),因为这是表达您想要b在两个条件下进行过滤的最清晰的方式,而不会影响a正在返回的行。


推荐阅读