我确实犯了一个愚蠢的错误,但我无法弄清楚:
在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行
答案 0 :(得分:63)
SELECT distinct idCustomer FROM reservations
WHERE DATEPART ( hour, insertDate) < 2
and idCustomer is not null
确保list参数不包含空值。
以下是解释:
WHERE field1 NOT IN (1, 2, 3, null)
与:
相同WHERE NOT (field1 = 1 OR field1 = 2 OR field1 = 3 OR field1 = null)
(*)编辑:这个解释非常好,但我想解决一件事,以避免未来的挑选。 (TRUE或NULL)将评估为TRUE。例如,如果field1 = 3,则这是相关的。该TRUE值将被否定为FALSE并且该行将被过滤。
答案 1 :(得分:6)
在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)'
答案 2 :(得分:2)
鉴于它是SQL 2005,你也可以试试这个 它类似于Oracle的MINUS命令(与UNION相反)
但我还建议为调试添加DATEPART(hour,insertDate)列
SELECT idCustomer FROM reservations
EXCEPT
SELECT idCustomer FROM reservations WHERE DATEPART ( hour, insertDate) < 2
答案 3 :(得分:0)
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,这显然是原始海报的主要问题]
答案 4 :(得分:0)
很抱歉,如果我错过了这一点,但是下面会不会按照自己的意愿行事吗?
SELECT distinct idCustomer FROM reservations
WHERE DATEPART(hour, insertDate) >= 2
答案 5 :(得分:-1)
SELECT MIN(A.maxsal) secondhigh
FROM (
SELECT TOP 2 MAX(EmployeeBasic) maxsal
FROM M_Salary
GROUP BY EmployeeBasic
ORDER BY EmployeeBasic DESC
) A
答案 6 :(得分:-1)
select * from table_name where id=5 and column_name not in ('sandy,'pandy');