Pergunta de pesquisa SQL: seleccione ... não em

Tenho a certeza que estou a cometer um erro estúpido, mas não consigo perceber o quê.

no servidor sql 2005 estou a tentar seleccionar todos os clientes excepto aqueles que fizeram uma reserva antes das 2 da manhã.

Quando eu executar esta pesquisa:

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

Mas

SELECT idCustomer FROM reservations 

Devolve 152 000 resultados e a parte "não está":

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

devolve apenas 284 linhas

Author: sblundy, 2008-11-17

7 answers

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

Certifique-se que o parâmetro da sua lista não contém valores nulos.

Eis uma explicação:
WHERE field1 NOT IN (1, 2, 3, null)

É o mesmo que:

WHERE NOT (field1 = 1 OR field1 = 2 OR field1 = 3 OR field1 = null)
    A última comparação é considerada nula.
  • esse nulo é ou é feito com o resto da expressão booleana, rendendo nulo. (*)
  • null é negada, rendendo nula.
  • null não é verdadeiro - a cláusula onde só mantém linhas verdadeiras, por isso todas as linhas são filtradas.

(*) editar: esta explicação é muito bem, mas gostaria de me dirigir a uma coisa para evitar futuras picaretas. (Verdadeiro ou nulo) avaliaria para verdadeiro. Isto é relevante se field1 = 3, por exemplo. Esse valor verdadeiro seria negado para falso e a linha seria filtrada.

 56
Author: Amy B, 2015-09-14 20:13:41

É sempre perigoso ter NULL na lista IN - muitas vezes comporta-se como esperado para o IN mas não para o 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)'
 6
Author: Cade Roux, 2008-11-17 18:40:51

Dado que é SQL 2005, Você também pode tentar isto É semelhante ao comando MINUS da Oracle (oposto da União)

Mas eu também sugeriria a adição da coluna DATEPART (Hora, data de inserção) para a depuração

SELECT idCustomer FROM reservations 
EXCEPT
SELECT idCustomer FROM reservations WHERE DATEPART ( hour, insertDate) < 2
 2
Author: jerryhung, 2008-11-17 17:09:50
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

[actualização: adicionou critérios adicionais para lidar com o facto de o idcustómero ser nulo, que era aparentemente a principal questão que o cartaz original tinha]

 0
Author: Kevin Fairchild, 2008-11-17 17:35:10
Desculpa se não percebi, mas o seguinte não faria o que queres sozinho?
SELECT distinct idCustomer FROM reservations 
WHERE DATEPART(hour, insertDate) >= 2
 0
Author: Aidan Kane, 2015-08-05 09:16:14
SELECT MIN(A.maxsal) secondhigh
FROM (
      SELECT TOP 2 MAX(EmployeeBasic) maxsal
      FROM M_Salary
      GROUP BY EmployeeBasic
      ORDER BY EmployeeBasic DESC
     ) A
 -1
Author: Akash Pawar, 2017-01-19 06:43:35
select * from table_name where id=5 and column_name not in ('sandy,'pandy');
 -1
Author: santhosh, 2017-07-04 11:40:47