2017-07-25 52 views
0

我有两个字段,其中#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 

然而,这是很不理想的,所以我wondering-任何方式来写这个有更好的表现/看起来更干净或更简单?为了澄清这个查询的工作原理(第二个查询),我想知道是否有更好的方法来编写它。

谢谢!

+0

您需要澄清问题是否在列为null或者在两种情况下都可以填充它们,并且您想要加入。 – scsimon

+0

我说这个问题不是说a.rep_email_adress是null(它不是) - 但只是与b.email不匹配;然而,a.email字段确实如此,所以如果rep_email_address没有加入(不是因为它是空的,而是根本没有加入),我想要加入邮件字段。 – edost4

+0

嗯,哟在这种情况下说,但这并不明确,它可能是和/或不能为null,但谢谢澄清 – scsimon

回答

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. 
+0

信不信由你,在第一个rep_email_address匹配的情况下,这会导致重复,然后邮件匹配。虽然我的查询不是 – edost4

+0

你介意分享这3种情况的预期输出 - (i)其中只有rep_email_address与b.email相匹配(ii)只有a.email与b.email匹配且(iii)其中a.rep_email_address和a.email是相同的,他们匹配b.email? – DeadLock

+2

将不同添加到选择。您不会因为使用union all而受到重复@ edost4 – scsimon

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,杰森

+0

谢谢你也工作! – edost4

1

SQL服务器在布尔评估采用“Three-Valued Logic”:

  • NULL <> 2 - >未知(在WHERE子句就会在你的情况基本上成为假)
  • NULL <> NULL - >未知(同上)
  • a <> b - >真

在你的情况你的原始查询应该是:

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 s到表示空字符串,因为这需要大量的额外代码,然后检查NULL小号

+0

该查询的结果与DeadLock's即ie相同。它重复了一些记录。虽然我的查询不是 – edost4

+0

这意味着您在#email表中有多个匹配的记录。正如@scsimon所提到的那样,你的猫尝试不同的 – Alex

+0

谢谢Alex! – edost4