PDA

Ver la Versión Completa : Seleccionar valores nulos


hector.roma
22-07-2005, 17:01:20
Hola, tengo un ligero problema que me está volviendo loco. No sé si es por estar trabajando sin dormir por la noche... o por cualquier otra razón. Voy al grano, imaginemos una tabla del estilo:

Tabla: MiTabla
Codigo Nombre Presente
------ ------- --------
1 Paco T
2 Pepe F
3 Luis (null)
4 Mara (null)
5 Rosa (null)
6 Tono F

Ahora bien cuando ejecuto la consulta:

SELECT *
FROM MiTabla
WHERE Presente <> "T"


Mi pregunta es... ?no debería aparecer en el resultado los registros del 2 al 6?

Ya se que se soluciona poniendo WHERE Presente="F" AND Presente="NULL" pero ahora me asalta la duda:

si lo anterior es correcto, y de serlo ?porqué no muestra ningún registro (creo que esto no lo había dicho antes, pues eso la consulta anterior no me muestra ninguna fila)?
y en el caso de no ser correcto, ?cual es mi error?
Muchas gracias a todos, perdón por escribir algo tan sencillo, pero con el calor que hace mi cabeza hoy no regula bien... Gracias.
PD: Mi teclado no tiene el símbolo de abertura de interrogación.

ContraVeneno
22-07-2005, 17:08:11
Prueba con

WHERE (Presente='F') OR (Presente is Null)


Ya que la sentencia Y (AND) hace que las dos partes tenga que ser verdaderas, lo cuál sería un poquito complicado :D
aunque lo correcto sería que si vas a utilizar un campo tipo boolean, lo definas en tu tabla como tipo boolean (bit para SQL server).

Aunque si podría ser el no dormir, quieras o no la mente no trabaja igual. :D :D

hector.roma
22-07-2005, 17:15:48
Pues eso, no puedo hacerlo en un sólo paso? Es decir, es restriccion del SQL que si selecciono aquellos registros diferentes de "T", por ejemplo, no muestre aquellos que tienen valor null? y sí solamente aquellos en los que el valor como bien le he solicitado es UN VALOR (y que sea valor) diferente de "T".

PD1: Por razones de mi entorno de desarrollo, no existe el tipo Boolean... se sustituye por un string de 1 caracter

PD2: De todos modos gracias.

ContraVeneno
22-07-2005, 18:03:29
ya lo probaste con el OR???

hector.roma
22-07-2005, 19:16:55
La solución que yo proponía tenía el error... ehem... tipográfico del "AND", pero mi intención no era dar una solución "real". Mi intención siempre fue saber si lo podía hacer en un solo paso sin necesidad de "AND" o de "OR". Como es lógico pensar si le digo explícitamente al SQL que haga algo con los valores nulos lo va a hacer... el problema mío era conocer una alternativa para mostrar esos nulos sin necesidad de montar la candena ...OR Campo IS NULL.

Voy a empezar a firmar con ... datos correctos salvo error tipográfico y válidos hasta fin de stock. :D

ContraVeneno
22-07-2005, 19:36:59
Originalmente publicado por hector.roma
mostrar esos nulos sin necesidad de montar la candena ...OR Campo IS NULL.

Para esta cuestión no se si se pueda cambiar algo en la configuración o hacer algo extra. En pocas palabras, no lo se :o

De cualquier manera, bienvenido a los foros y te recomiendo dos cositas que podrían servirte mucho.

Guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php)
Uso de las etiquetas (http://www.clubdelphi.com/foros/misc.php?do=bbcode)

Saludos

jachguate
22-07-2005, 19:41:40
El problema aqui es que no has entendido la lógica de tres estados que usa SQL.

Trataré de explicarla de manera breve usando tu caso como ejemplo, puesto que no dispongo ahora de un vínculo a un artículo serio y bien redactado. De antemano me disculpo por cualquier error que pueda cometer en la forma, puesto que mi oficio no es el de escritor.

Lógica de 3 estados en SQL
by jachguate.

En SQL cualquier variable, incluyendo las booleanas puede tener valor NULL.

Cuando haces comparaciones, que devuelven un valor booleano, estas pueden devolver Verdadero, Falso o también NULL, que es algo a lo que no estamos acostumbrados cuando comenzamos con SQL y que regularmente ocasiona este tipo de confusiones.

Revisemos primero que significa el valor NULL: Desconocido o ausencia de valor.

Así, la comparación de desigualdad que estas aplicando sigue la siguiente lógica:


Comparando Presente <> T

Cod Nombre Presente Comparación
--- ------ -------- -----------
1 Paco T Falso
2 Pepe F Verdadero
3 Luis NULL NULL
4 Mara NULL NULL
5 Rosa NULL NULL
6 Tono F Verdadero


Se incluirán en el resultado solamente aquellos registros cuya comparación devuelva Verdadero (solamente los que tienen Falso).

Esto tiene sentido, dado que NULL es desconocido. SQL piensa de esta forma:

Es Desconocido(null) Diferente de Verdadero, pues no lo se, entonces el resultado es Desconocido(null). Dado que desconocido podria ser verdadero o falso.

Por eso, tampoco podrias comparar así:
WHERE Presente="F" or Presente="NULL"

pues obtendrias exactamente el mismo resultado... dado que tampoco sabemos si desconocido es igual a desconocido. Para ello, SQL ha inventado el operador is null.

Así, la consulta adecuada sería:


Select *
from MiTabla
where Presente <> 'T'
or Presente is null;


Una forma de sortear esto también es valerse de una función como coalesceque regularmente devuelve el primer valor no nulo de sus parámetros, pero no existe en todos los motores:


Select *
from MiTabla
where coalesce(Presente, 'F') <> 'T'


Así, coalesce devolverá el valor de presente, o 'F' en caso que presente sea Null y la condición se cumplirá tal como deseas. En oracle, por ejemplo, la función a usar sería nvl.

Te recomiendo consultar la documentación de tu motor para ver si hay alguna función equivalente que esté disponible para vos.

También te recomiendo investigar un poco mas sobre el comportamiento de los valores nulos en general, pues probablemente te sorprenda que 5 + null => null, dado que 5 + desconocido => desconocido. :p

Hasta luego.

;)