2010-02-25 7 views
7

Me encontré con una situación extraña al tratar de contar el número de filas que NO tienen valores varchar especificados por una instrucción select. Ok, eso suena confuso incluso para mí, así que déjame darte un ejemplo:COUNT() La función junto con la cláusula NOT IN no funciona correctamente con el campo varchar (T-SQL)

Digamos que tengo un campo "MyField" en "SomeTable" y quiero contar en cuántas filas los valores MyField no pertenecen a un dominio definido por los valores de "MyOtherField" en "SomeOtherTable". En otras palabras, supongamos que tengo MyOtherField = {1, 2, 3}, quiero contar en cuántas filas el valor de MyField no es 1, 2 o 3. Para eso, usaría la siguiente consulta:

SELECT COUNT(*) FROM SomeTable 
WHERE ([MyField] NOT IN (SELECT MyOtherField FROM SomeOtherTable)) 

Y funciona como un encanto. Sin embargo, tenga en cuenta que MyField y MyOtherField están int tipados. Si trato de ejecutar exactamente la misma consulta, a excepción de los campos de tipo varchar, su valor de retorno es 0, aunque sé que hay valores incorrectos, ¡los puse allí! Y si, sin embargo, trato de contar lo opuesto (cuántas filas TENGO en el dominio opuesto a lo que quiero es cuántas filas no) simplemente suprimiendo la cláusula "NO" en la consulta anterior ... Bueno, ESO ¡trabajos! ¬¬

Sí, debe haber un montón de soluciones, pero me gustaría saber por qué no funciona como debería. Además, no puedo simplemente modificar toda la consulta ya que la mayoría está construida dentro de un código C# y básicamente la única parte que tengo la libertad de cambiar que no tendrá impacto en ninguna otra parte del software es la declaración seleccionada que corresponde al dominio (lo que viene en la cláusula NOT IN). Espero haber dejado en claro que alguien podría ayudarme.

Gracias de antemano.

+1

¿Tiene NULL marcas en ese "SomeOtherTable" para ese campo? –

Respuesta

6

Para NOT IN, siempre es falso si la subconsulta devuelve un valor NULL. La respuesta aceptada al this question describe elegantemente por qué.

La anulabilidad de un valor de columna es independiente del tipo de datos se utiliza con demasiada: muy probablemente sus columnas varchar tiene valores NULL

No hacer frente a esto, el uso que no existe. Para valores no nulos, que funciona igual que NO EN modo es compatible

SELECT COUNT(*) FROM SomeTable S1 
WHERE NOT EXISTS (SELECT * FROm SomeOtherTable S2 WHERE S1.[MyField] = S2.MyOtherField) 
+0

Gracias, utilizando su consulta sugerida con la cláusula NOT EXISTS hizo exatly lo que quería. –

0

GBN tiene una respuesta más completa, pero no puede ser molestado en recordar todo eso. En cambio, tengo el hábito religioso de filtrar los nulos de mis cláusulas IN:

SELECT COUNT(*) 
FROM SomeTable  
WHERE [MyField] NOT IN (
    SELECT MyOtherField FROM SomeOtherTable 
    WHERE MyOtherField is not null 
) 
Cuestiones relacionadas