我似乎需要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
)
还有更优雅的解决方案吗?
是的,我确实知道可以为空的外键。我只是在不改变表格/制作临时表/修改现有表格数据的情况下询问解决方案。
答案 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