如何INNER JOIN非空值但是在相同的时间左边加入空值?

时间:2014-06-19 15:45:42

标签: sql-server tsql left-join inner-join

我似乎需要MAGIC JOIN对非空值应该INNER JOIN,但同时对空值有效LEFT JOIN。通过"空"我的意思是一个非零的零长度char值,如下所示:''

我有表Customers

CustomerCode    Customer_AddressCode
CC01            AC01
CC02            somebullcrap
CC03
CC04            AC02
CC05

Addresses

AddressCode    AddressValue
AC01           City 01
AC02           City 02
AC03           City 03
AC04           City 04
AC05           City 05

所需的输出如下:

CustomerCode  AddressValue
CC01          City 01
CC03          NULL
CC04          City 04
CC05          NULL

所以它会省略somebullcrap表中不存在的代码Addresses的地址。

我能想到的最好的是:

SELECT c.CustomerCode, a.AddressValue
FROM Customers c
LEFT JOIN Addresses a ON a.AddressCode = c.Customer_AddressCode
WHERE c.Customer_AddressCode = ''
OR c.Customer_AddressCode IN
(
    SELECT AddressCode
    FROM Address
)

还有更优雅的解决方案吗?

是的,我确实知道可以为空的外键。我只是在不改变表格/制作临时表/修改现有表格数据的情况下询问解决方案。

4 个答案:

答案 0 :(得分:3)

为什么不

SELECT c.CustomerCode, a.AddressValue
FROM Customers c
LEFT JOIN Addresses a 
   ON a.AddressCode = c.Customer_AddressCode
WHERE c.Customer_AddressCode = ''
   OR a.AddressValue IS NOT NULL

答案 1 :(得分:0)

你想要的只是一个左连接,因为地址表中没有空字符串作为代码的地址。我认为这会给你想要的结果:

SELECT c.CustomerCode, a.AddressValue
FROM Customers c
LEFT JOIN Addresses a ON a.AddressCode = c.Customer_AddressCode

为什么客户和地址之间的外键没有检查?

答案 2 :(得分:0)

如果您的问题是处理空字符串(''),您可以使用简单的

CASE Customer_AddressCode='' THEN NULL ELSE Customer_AddressCode END

将空字符串转换为真实的NULL值 然后,这样一个简单的LEFT JOIN

SELECT c.CustomerCode, a.AddressValue
FROM 
(SELECT 
    CustomerCode, 
    CASE Customer_AddressCode='' THEN NULL ELSE Customer_AddressCode END AdCode
FROM Customers) c
LEFT JOIN Addresses a ON (a.AddressCode = c.AdCode OR c.AdCode is null)

c.AdCode is null条件将允许结果中的空值,同时过滤您似乎不想要的“somebullcrap”。

答案 3 :(得分:0)

EricZ可能是最优雅的方法,可以返回正确的结果,但只是作为替代方案的练习:

SELECT  c.CustomerCode
      , a.AddressValue FROM    Customers c
        JOIN ( SELECT   AddressCode
                      , AddressValue
               FROM     Addresses
               UNION ALL
               SELECT   ''
                      , NULL
             ) a ON a.AddressCode = c.Customer_AddressCode