Вопрос 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 строк
Ответы
Ответ 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');