Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-07-2005
Avatar de hector.roma
hector.roma hector.roma is offline
Miembro
 
Registrado: jul 2005
Ubicación: a caballo entre Galicia y Portugal
Posts: 58
Poder: 19
hector.roma Va por buen camino
Seleccionar valores nulos

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:
Código SQL [-]
  
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.
Responder Con Cita
  #2  
Antiguo 22-07-2005
Avatar de ContraVeneno
ContraVeneno ContraVeneno is offline
Miembro
 
Registrado: may 2005
Ubicación: Torreón, México
Posts: 4.738
Poder: 23
ContraVeneno Va por buen camino
Prueba con
Código SQL [-]
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
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.
__________________


Última edición por ContraVeneno fecha: 22-07-2005 a las 17:12:27.
Responder Con Cita
  #3  
Antiguo 22-07-2005
Avatar de hector.roma
hector.roma hector.roma is offline
Miembro
 
Registrado: jul 2005
Ubicación: a caballo entre Galicia y Portugal
Posts: 58
Poder: 19
hector.roma Va por buen camino
No hay forma de hacerlo con una sola condición....

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.

Última edición por hector.roma fecha: 22-07-2005 a las 17:18:03. Razón: Complementar
Responder Con Cita
  #4  
Antiguo 22-07-2005
Avatar de ContraVeneno
ContraVeneno ContraVeneno is offline
Miembro
 
Registrado: may 2005
Ubicación: Torreón, México
Posts: 4.738
Poder: 23
ContraVeneno Va por buen camino
ya lo probaste con el OR???
__________________

Responder Con Cita
  #5  
Antiguo 22-07-2005
Avatar de hector.roma
hector.roma hector.roma is offline
Miembro
 
Registrado: jul 2005
Ubicación: a caballo entre Galicia y Portugal
Posts: 58
Poder: 19
hector.roma Va por buen camino
ciertamente es OR

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
Cita:
... datos correctos salvo error tipográfico y válidos hasta fin de stock.
Responder Con Cita
  #6  
Antiguo 22-07-2005
Avatar de ContraVeneno
ContraVeneno ContraVeneno is offline
Miembro
 
Registrado: may 2005
Ubicación: Torreón, México
Posts: 4.738
Poder: 23
ContraVeneno Va por buen camino
Cita:
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

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

Guía de estilo
Uso de las etiquetas

Saludos
__________________

Responder Con Cita
  #7  
Antiguo 22-07-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cool

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:

Código:
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:

Código SQL [-]
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:

Código SQL [-]
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.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 18:19:38.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi