Подтвердить что ты не робот

Вопрос SQL-запроса: SELECT... NOT IN

Я уверен, что совершу глупую ошибку, но не могу понять, что:

В SQL Server 2005 я пытаюсь выбрать всех клиентов, кроме тех, кто сделал резервирование до 2 часов утра.

Когда я запускаю этот запрос:

SELECT idCustomer FROM reservations 
WHERE idCustomer NOT IN 
  (SELECT distinct idCustomer FROM reservations 
   WHERE DATEPART ( hour, insertDate) < 2)

Я получаю 0 результатов.

Но

SELECT idCustomer FROM reservations 

возвращает 152 000 результатов и часть "NOT IN":

SELECT distinct idCustomer FROM reservations 
WHERE DATEPART ( hour, insertDate) < 2

возвращает только 284 строк

4b9b3361

Ответ 1

SELECT distinct idCustomer FROM reservations
WHERE DATEPART ( hour, insertDate) < 2
  and idCustomer is not null

Убедитесь, что ваш параметр списка не содержит нулевых значений.

Вот объяснение:

WHERE field1 NOT IN (1, 2, 3, null)

совпадает с:

WHERE NOT (field1 = 1 OR field1 = 2 OR field1 = 3 OR field1 = null)
  • Последнее сравнение оценивается как null.
  • Этот null равен OR'd с остальным булевым выражением, давая null. (*)
  • null отрицается, уступая null.
  • null неверно - предложение where сохраняет только истинные строки, поэтому все строки фильтруются.

(*) Редактировать: это объяснение довольно хорошее, но я хочу обратиться к одной вещи, чтобы предотвратить будущий nit-picking. (TRUE OR NULL) будет оцениваться как TRUE. Это актуально, если поле1 = 3, например. Это значение TRUE будет отменено до FALSE, и строка будет отфильтрована.

Ответ 2

Всегда всегда иметь NULL в списке IN - он часто ведет себя как ожидалось для IN, но не для NOT IN:

IF 1 NOT IN (1, 2, 3, NULL) PRINT '1 NOT IN (1, 2, 3, NULL)'
IF 1 NOT IN (2, 3, NULL) PRINT '1 NOT IN (2, 3, NULL)'
IF 1 NOT IN (2, 3) PRINT '1 NOT IN (2, 3)' -- Prints
IF 1 IN (1, 2, 3, NULL) PRINT '1 IN (1, 2, 3, NULL)' -- Prints
IF 1 IN (2, 3, NULL) PRINT '1 IN (2, 3, NULL)'
IF 1 IN (2, 3) PRINT '1 IN (2, 3)'

Ответ 3

Учитывая это SQL 2005, вы также можете попробовать Он похож на команду Oracle MINUS (напротив UNION)

Но я бы также предложил добавить столбец DATEPART (hour, insertDate) для отладки

SELECT idCustomer FROM reservations 
EXCEPT
SELECT idCustomer FROM reservations WHERE DATEPART ( hour, insertDate) < 2

Ответ 4

SELECT Reservations.idCustomer FROM Reservations (nolock)
LEFT OUTER JOIN @reservations ExcludedReservations (nolock) ON Reservations.idCustomer=ExcludedReservations.idCustomer AND DATEPART(hour, ExcludedReservations.insertDate) < 2
WHERE ExcludedReservations.idCustomer IS NULL AND Reservations.idCustomer IS NOT NULL
GROUP BY Reservations.idCustomer

[Обновление: добавлены дополнительные критерии для обработки idCustomer, являющегося NULL, что было, по-видимому, основной проблемой, с которой был оригинал плаката]

Ответ 5

Извините, если я пропустил этот момент, но не сделал бы то, что вы хотите от него?

SELECT distinct idCustomer FROM reservations 
WHERE DATEPART(hour, insertDate) >= 2

Ответ 6

SELECT MIN(A.maxsal) secondhigh
FROM (
      SELECT TOP 2 MAX(EmployeeBasic) maxsal
      FROM M_Salary
      GROUP BY EmployeeBasic
      ORDER BY EmployeeBasic DESC
     ) A

Ответ 7

select * from table_name where id=5 and column_name not in ('sandy,'pandy');