在日期上对null = null进行连接

时间:2013-10-19 23:51:19

标签: sql-server-2008 tsql

我想在日期字段上加入两个表

INNER JOIN ##MetricBase
ON  A.MetricID = ##MetricBase.MetricID
AND     A.ImportDate = ##MetricBase.ImportDate

如果日期为空,我还希望数据匹配。

是否比

更清洁
 INNER JOIN ##MetricBase
 ON    A.MetricID = ##MetricBase.MetricID
 AND   (A.ImportDate = ##MetricBase.ImportDate OR
        A.ImportDate IS NULL AND  ##MetricBase.ImportDate IS NULL)

附录

有些评论建议我避免空日期。此查询是分组集

的一部分
 GROUP BY GROUPING SETS(
(BossID, ID, ImportDate),
(BossID, ImportDate),
(BossID),
(BossID, ID),
(ImportDate),
()
)

Null将成为数据集的一部分

2 个答案:

答案 0 :(得分:2)

目前有一个MS Connect Request支持IS DISTINCT FROM,这是正确的ISO方式。缺乏支持目前是一个痛苦的问题,而你已经采取的方式实际上在技术上是正确的。

有人确实找到了clever workaround,但并不适用于所有情景。在你的情况下,我相信它会写成:

INNER JOIN ##MetricBase
ON A.MetricID = ##MetricBase.MetricID
AND EXISTS(SELECT A.ImportDate INTERSECT SELECT ##MetricBase.ImportDate)

据说,最近版本的SQL Server非常擅长优化它。

答案 1 :(得分:1)

从逻辑上讲,你无法进一步减少这一点,因为由于许多其他原因,null不等于任何东西,甚至本身。

在一个谓词中保留它的句法技巧是使用COALESCE和'magic'值。如果没有运行测试,我不知道有什么影响,这会对性能造成影响。我相信你对这两个条件的明确陈述(等于OR都为null)更清晰,更易于维护。但是为了思想,这里是COALESCE版本:

DECLARE @nullDate date = '04-02-4242';

...
ON A.MetricID   = ##MetricBase.MetricID
AND COALESCE(A.ImportDate           , @nullDate) = 
    COALESCE(##MetricBase.ImportDate, @nullDate)