SQL Server Left Join 奇怪的 NULL 检查

Ube*_*en1 6 null sql-server sql-server-2008-r2

我刚刚经历了一些旧的存储过程,做了一些优化,偶然发现了这个奇怪的地方:

SELECT ISNULL(bt.BusinessTypeID, 0) AS BusinessTypeID
FROM BusinessType bt
LEFT JOIN Business b
     ON b.BusinessTypeID = ISNULL(bt.BusinessTypeID, NULL)
Run Code Online (Sandbox Code Playgroud)

这是一个稍微简化的版本,但第 4 行是有问题的行。我无法想象这有什么作用?我已经检查了带有和不带有此 NULL 检查的 exec 计划和​​结果,一切似乎都一样。

这只是完全的疯狂还是有一些模糊的原因为什么离开它可能是有益的?

更新:

为了回应评论,在下面添加了完整的查询(匿名),在这个完整版本中,这ON Object4.Column9 = Function4(Object1.Column4, ?)对应于这个ON b.BusinessTypeID = ISNULL(bt.BusinessTypeID, NULL)。另外 Object4.Column9 是一个可以为空的外键 & Object1.Column4 是一个不可为空的主键

SELECT Function1() AS Column1,
Function2(Function3(Function2((
    SELECT Column2 AS Column3
    FROM 
    (
            SELECT ? AS Column4,
                ? AS Column2
            WHERE (Variable1 IS NULL OR ? = Variable1)

            UNION ALL

            SELECT Function4(Object1.Column4, ?) AS Column4,
                Function4(Object1.Column5,?) + ? AS Column2
            FROM Object2 Object1
            WHERE Object1.Column6 = Variable2
                AND (Variable1 IS NULL OR Object1.Column4 = Variable1)
                AND Object1.Column7 = ?
    ) Object3
    ORDER BY Column4 ASC
    FOR XML PATH (?))), ?, ?, ?)) AS Column8

UNION ALL

SELECT Object3.Column1,
Function2(Function3(Function2((
    SELECT Function4(Column8, ?) AS Column3
    FROM 
    (
            SELECT DISTINCT Function4(Object4.Column9, ?) AS Column4,
                Function4(CAST(Function5(Object4.Column10) OVER (PARTITION BY Function4(Object4.Column9, ?)) AS nvarchar(7)), ?) + ? AS Column8
            FROM Object5 Object4
            WHERE Object4.Column6 = Variable2
                AND (Variable1 IS NULL OR Function4(Object4.Column9, ?) = Variable1)
                AND MultiPartIdentifier1.Function6(Variable3, Object4.Column11, ?) = Object3.Column1
                AND (Variable4 = ? AND (Object4.Column12 = Variable5 OR (Variable5 IS NULL AND(Variable6 IS NULL OR Object4.Column12 IN (SELECT Column13 FROM Schema1.Object6(Variable6, ?)))))
                    OR (Variable4 = ? AND (Variable7 = ? OR (Variable7 = ? AND (Object4.Column12 IS NULL OR (Object4.Column12 IN (SELECT Column13 FROM Schema1.Object6(Variable6, ?))))))))

            UNION ALL

            SELECT Function4(Object1.Column4, ?) AS Column4,
                Function4(CAST(Function5(Object4.Column10) OVER (PARTITION BY Function4(Object1.Column4, ?)) AS nvarchar(7)), ?) + ? AS Column8
            FROM Object2 Object1
            LEFT JOIN Object5 Object4
                ON Object4.Column9 = Function4(Object1.Column4, ?)
                AND MultiPartIdentifier1.Function6(Variable3, Object4.Column11, ?) = Object3.Column1
                AND (Variable4 = ? AND (Object4.Column12 = Variable5 OR (Variable5 IS NULL AND(Variable6 IS NULL OR Object4.Column12 IN (SELECT Column13 FROM Schema1.Object6(Variable6, ?)))))
                    OR (Variable4 = ? AND (Variable7 = ? OR (Variable7 = ? AND (Object4.Column12 IS NULL OR (Object4.Column12 IN (SELECT Column13 FROM Schema1.Object6(Variable6, ?))))))))
            WHERE Object1.Column6 = Variable2
                AND (Variable1 IS NULL OR Function4(Object1.Column4, ?) = Variable1)
                AND Object1.Column7 = ?
                AND Object4.Column9 IS NULL
    ) Object7
    WHERE (Variable1 IS NULL OR Function4(Object7.Column4, ?) = Variable1)
    ORDER BY Column4 ASC
    FOR XML PATH (?))), ?, ?, ?)) AS Column8
FROM 
(
SELECT DISTINCT MultiPartIdentifier1.Function6(Variable3, Object4.Column11, ?) AS Column1
FROM Object5 Object4
WHERE Object4.Column6 = Variable2
    AND (Variable1 IS NULL OR Function4(Object4.Column9, ?) = Variable1)
    AND Object4.Column11 BETWEEN MultiPartIdentifier1.Function6(Variable3, Variable8, ?) AND Variable9
    AND (Variable4 = ? AND (Object4.Column12 = Variable5 OR (Variable5 IS NULL AND(Variable6 IS NULL OR Object4.Column12 IN (SELECT Column13 FROM Schema1.Object6(Variable6, ?)))))
        OR (Variable4 = ? AND (Variable7 = ? OR (Variable7 = ? AND (Object4.Column12 IS NULL OR (Object4.Column12 IN (SELECT Column13 FROM Schema1.Object6(Variable6, ?))))))))
) Object3
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 8

你是对的,代码在很多地方都没有什么意义。

  • 这部分尤其是完全多余的:

    ISNULL(bt.BusinessTypeID, NULL)
    
    Run Code Online (Sandbox Code Playgroud)

    无论是否可以为空,您都可以使用whatever代替。ISNULL(whatever, NULL)whatever

  • 另一部分ISNULL(bt.BusinessTypeID, 0)也不需要,但只是因为bt.BusinessTypeID它不可为空(它是表的 PK)并且它位于LEFT外部联接的左侧。因此,当它到达该SELECT列表时,它永远不会为空。

代码可以安全地替换为:

SELECT bt.BusinessTypeID
FROM BusinessType bt
LEFT JOIN Business b
     ON b.BusinessTypeID = bt.BusinessTypeID
Run Code Online (Sandbox Code Playgroud)

我的猜测是,编写该代码的人都有一个通用表达式模式,该模式适用于可为空和不可为空的表达式和参数,并且不太关心简化代码。例如:

ON x.eXampleID = ISNULL(y.eXampleID, -1)

WHERE x.eXampleID = ISNULL(y.eXampleID, -1) 

SELECT ISNULL(y.eXampleID, 0) AS eXampleID
Run Code Online (Sandbox Code Playgroud)

在某些情况下可能工作正常(即使它们不是最有效的),其中 of 的第一个参数ISNULL()是一个可为空的表达式,第二个参数不是NULL