2014-11-25 4 views
-1

Сначала я хотел бы сказать, что я понимаю, что вы не можете сравнивать null в предложении where без использования is null или not null. Моя проблема заключается в том, что в следующем запросе предложение where не всегда возвращает null. Он возвращает только null, когда в выражении select в скобках нет записей.Null values ​​in where clause

Я ищу способ обработки нулей, возвращаемых из оператора select в предложении where. Этот запрос должен возвращать список маршрутов, которые не указаны в таблице. Это будет использоваться, чтобы пользователи могли видеть только то, чего нет в таблице.

Могу ли я использовать 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 
+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 
+0

работал отлично –

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) 
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 
     ); 

NULL Он обрабатывает должным образом (который NOT IN не будет), а не приведет к ошибке если ваш подзапрос возвращает более одной строки (с использованием <> приведет к ошибке), и он может использовать анти-полу-соединение, что приводит к better performance, чем к LEFT JOIN/IS NULL.

Я сделал несколько изменений в код тоже, большинство из которых прямо из Aaron Bertrand's "Bad Habits to Kick" series

Некоторые из них немного субъективны, но я hink каждая статья делает довольно убедительный случай для каждого изменения.