我有两张桌子customer_details
和address_details
。我想用他们相应的地址显示客户详细信息,所以我使用的是LEFT JOIN
,但是当我执行此查询时,SQL Server会丢弃customer_details表的street_no
与address_detials表中的street_no不匹配的行,并且只显示行customer_detials的“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
现在很明显你used b.case_id=1
,我将解释为什么它过滤:
LEFT JOIN本身返回一些行,这些行包含结果集中表b
的所有NULL值,这是您想要的和期望的。
但是通过使用WHERE b.case_id=1
,包含表b
的NULL值的行将被过滤掉,因为它们都不匹配条件(所有这些行都有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-out b
值:
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
行。
我认为Wilhelm Poggenpohl的回答是对的。您只需将最后一个连接条件a.case_id = 1更改为b.case_id = 1
select a.* , b.address
from customer_details a
left join address_details b on a.street_no=b.street_no
and b.case_id=1
此查询将显示来自customer_details
的每一行和相应的地址,如果有street_no
的匹配且地址符合条件case_id=1
。
这是因为where子句。试试这个:
select a.* , b.address
from customer_details a
left join address_details b on a.street_no=b.street_no
and a.case_id=1