我在#data表中有两个带有电子邮件地址的字段,我正在尝试加入。我希望它加入代表电子邮件地址,如果这不起作用,我希望它加入电子邮件。我尝试运行以下查询:
select a.*
from #data a
join #email b on b.email=coalesce(a.rep_email_address,a.email)
where a.rep_email_address<>a.email
然而,这不起作用,因为在a.rep_email_adress不为空但与b.email不匹配的情况下,它将删除记录而不是取a.email字段。
这是我找到的解决办法:
select a.*
from #data a
join #email b on a.email=b.email
except
select a.*
from #data a
join #email b on a.rep_email_address=b.email
union
select a.*
from #data a
join #email b on a.rep_email_address=b.email
where a.rep_email_address<>a.email
然而,这远非最佳,所以我想知道 - 任何方式写这个以表现更好/看起来更清洁或更简单?只是为了澄清 - 这个查询有效(第二个查询),我想知道是否有更好的方法来编写它。
谢谢!
答案 0 :(得分:3)
这应该简单得多。但是,我还建议您检查此查询的执行计划,以帮助您分析是否更优化。 [或者只是比较表格上的执行时间]
SELECT a.*
FROM #data a
JOIN #email b
ON (a.rep_email_address = b.email
OR a.email = b.email )
WHERE a.rep_email_address<>a.email;
# Not sure why or IF you need this where clause specifically.
答案 1 :(得分:1)
尝试这样......
SELECT
a.*,
SomeColumn = ISNULL(e1.SomeColumn, e2.SomeColumn)
from
#data a
LEFT JOIN #email e1
ON e1.email = a.rep_email_address
LEFT JOIN #email e2
ON e2.email = a.email
AND e1.email IS NULL
WHERE
a.rep_email_address <> a.email
AND (
e1.email IS NOT NULL
OR
e2.email IS NOT NULL
);
HTH,Jason
答案 2 :(得分:1)
SQL服务器在布尔评估中使用“Three-Valued Logic”:
NULL <> 2
- &gt;未知(在你的情况下,在where子句中它将基本上变为假)NULL <> NULL
- &gt;未知(与上述相同)a <> b
- &gt;真在您的情况下,您的原始查询应为:
select a.*
from #data a
join #email b on b.email=coalesce(a.rep_email_address,a.email)
where ISNULL( a.rep_email_address, '' ) <> ISNULL( a.email, '' )
如果您关心性能,请尽量避免在连接谓词或WHERE
条件中使用函数,因为这会阻止SQL Server在传递给函数的列上使用索引。
SELECT a.*
FROM #data AS a
INNER JOIN #email AS b ON b.email = a.rep_email_address OR b.email = a.email
WHERE a.rep_email_address <> a.email OR ( a.rep_email_address IS NULL OR a.email IS NULL )
要点:
不要使用NULL
来表示空字符串,因为这需要大量额外代码才能检查NULL
s