where子句中的空值

时间:2014-11-25 16:59:51

标签: sql-server tsql null

首先,我想说我明白,如果不使用nullis null,则无法在where子句中进行比较not null。我的问题是,通过下面的查询,where子句并不总是返回null。当括号内的select语句中没有记录时,它只返回null。

我正在寻找一种方法来处理where子句中select语句返回的空值。此查询应返回未在表中列出的路由列表。这将被利用,以便用户只能看到表中没有的内容。

我可以使用if选择返回null然后选择全部吗?

declare @CollectionDate datetime = '11/25/2014'
declare @Inspector int = 12

SELECT RouteID,CONVERT(nvarchar(10), RouteID) + ' - ' + AbbreviatedRoute AS [RouteName] 
FROM MasterTable.TrapTruckRoutes 
where routeID <>

(

select a.routeID 
from Trapping.RainDetail a 
join trapping.Rain b 
on a.RainID = b.RainID 
where b.CollectionDate = @collectionDate 
and b.InspectorID = @inspector

)

ORDER BY RouteID

3 个答案:

答案 0 :(得分:2)

你可以尝试类似LEFT JOIN的东西,它将从左表中选择所有记录并将其与右表中有匹配的记录连接起来。没有匹配将具有空值。

尝试这样的事情:

SELECT X.RouteID,CONVERT(nvarchar(10), X.RouteID) + ' - ' + AbbreviatedRoute AS [RouteName] 
FROM MasterTable.TrapTruckRoutes AS X LEFT JOIN (
    SELECT A.routeID 
    FROM Trapping.RainDetail A 
    JOIN trapping.Rain B 
    ON A.RainID = B.RainID 
    WHERE B.CollectionDate = @collectionDate 
                AND B.InspectorID = @inspector
) AS Y
ON X.routeID = Y.routeID
WHERE Y.routeID IS NULL
ORDER BY X.RouteID

答案 1 :(得分:1)

试试这个。

SELECT RouteID,
       CONVERT(NVARCHAR(10), RouteID) + ' - '
       + AbbreviatedRoute AS [RouteName]
FROM   MasterTable.TrapTruckRoutes b
WHERE  routeID = (SELECT CASE
                           WHEN a.routeID IS NULL THEN b.routeID
                           ELSE a.routeID
                         END
                  FROM   Trapping.RainDetail a
                         JOIN trapping.Rain b
                           ON a.RainID = b.RainID
                  WHERE  b.CollectionDate = @collectionDate
                         AND b.InspectorID = @inspector) 

答案 2 :(得分:1)

我倾向于使用NOT EXISTS

DECLARE @CollectionDate DATETIME = '20141125';
DECLARE @Inspector INT = 12;

SELECT  RouteID,
        RouteName = CONVERT(NVARCHAR(10), RouteID) + ' - ' + AbbreviatedRoute 
FROM    MasterTable.TrapTruckRoutes AS ttr
WHERE   NOT EXISTS
        (   SELECT  1
            FROM    Trapping.RainDetail AS rd
                    INNER JOIN trapping.Rain AS r
                        ON r.RainID = rd.RainID
            WHERE   r.CollectionDate = @CollectionDate
            AND     r.InspectorID = @Inspector
            AND     rd.RouteID = ttr.RouteID
        );

它正确处理NULLNOT IN赢了),如果您的子查询返回多行,则不会导致错误(使用<>将导致错误),并且能够使用导致better performance的反半连接而不是使用LEFT JOIN/IS NULL

我也对您的代码进行了一些更改,其中大部分内容都是Aaron Bertrand's "Bad Habits to Kick" series

其中一些是有点主观的,但我认为每篇文章都会为每次更改提供一个非常引人注目的案例。