Left Join muy simple...

20/06/2005 - 15:46 por David Perona | Informe spam
Hola a todos,
A ver si alguien me puede aclarar una duda que tengo.

Tengo una tabla de máquinas y otra de pólizas que pueden tener estas
máquinas. La primera, tiene como clave primaria los campos codemp y
codmaquina. La segunda, codemp, codmaquina y codcompañia.

Pues bien, necesito una consulta para obtener todas las máquinas,
independientemente de si tienen polizas asociadas o no. En la base de datos,
tengo un único registro en la tabla máquinas, y ninguno en la tabla pólizas.

Hasta hoy, tenia esta consulta:

SELECT P.CODEMP AS CODEMP_POLIZA, M.CODEMP AS CODEMP_MAQUINA, M.* FROM
MAQUINAS M
LEFT JOIN POLIZAS P ON M.CODMAQUINA = P.CODMAQUINA
WHERE M.CODEMP = '20'
AND (P.CODEMP = '20' OR P.CODEMP IS NULL)

Pues resulta que esta consulta no me muestra el registro de la tabla
máquina. Si en cambio, añado en la clausula ON la unión de los campos CODEMP
de ambas tablas, y quito el último AND de la clausula WHERE, la consulta se
comporta como es de esperar. Devuelve todos los datos de la tabla máquinas, y
con valor NULL, los campos correspondientes a la tabla Pólizas.
Entiendo que la sintaxis correcta para esta consulta es como os acabo de
contar, especificando en la clausula ON todos los campos que conforme la
clave principal en la tabla de la izquierda. Pero por otros motivos,
necesitamos montar la consulta de esta manera.

Pues bueno, despues de todo el tostón, alguien podría decirme porque se
comporta asi? No debería ser lo mismo igualar los campos clave en el apartado
ON, que filtrar luego los valores posibles de los campos en el apartado WHERE?

Muchas Gracias a TODOS, por haber leido hasta aqui ;)

Preguntas similare

Leer las respuestas

#6 Jorge Martinez
20/06/2005 - 23:49 | Informe spam
Amigo David, creo que el tema es el siguiente:

todo parte de la forma que tiene SQL Server de evaluar este tipo de
consultas, primero evalua o ejecuta la parte de la LEFT JOIN y despues
aplica el filtrado de filas segun la clausula WHERE. Esto nos lleva a ver
que la primera consulta que comentas nunca devolvera los valores que esperas
ya que al aplicar primero la LEFT JOIN y despues su filtrado este segundo
paso quita los registros cuyo campo p.codemp no se iguala con el de la
condicion. Los valores nulos que nos aparecen no forman parte de la tabla
por lo que no se pueden usar como filtro.


Sin embargo cuando se incluye la condicion dentro de la LEFT JOIN (que segun
Microsoft es la forma correcta de hacerlo) cuando se trae los registros de
ambas tablas, estos ya vienen filtrados desde el origen por su condicion de
filtrado (es mas puedes observar que la parte P.CODEMP IS NULL te sobraria)
y luego al aplicar la LEFT JOIN todo funciona correctamente.

Sobre todo quedate con el tema del orden de ejecucion y echale un vistazo a
los planes de ejecucion de las 2 consultas y observaras lo que te comento.


SalU2



"David Perona" <david.perona[borrar]esto]@telefonica.net> escribió en el
mensaje news:
Hola a todos,
A ver si alguien me puede aclarar una duda que tengo.

Tengo una tabla de máquinas y otra de pólizas que pueden tener estas
máquinas. La primera, tiene como clave primaria los campos codemp y
codmaquina. La segunda, codemp, codmaquina y codcompañia.

Pues bien, necesito una consulta para obtener todas las máquinas,
independientemente de si tienen polizas asociadas o no. En la base de


datos,
tengo un único registro en la tabla máquinas, y ninguno en la tabla


pólizas.

Hasta hoy, tenia esta consulta:

SELECT P.CODEMP AS CODEMP_POLIZA, M.CODEMP AS CODEMP_MAQUINA, M.* FROM
MAQUINAS M
LEFT JOIN POLIZAS P ON M.CODMAQUINA = P.CODMAQUINA
WHERE M.CODEMP = '20'
AND (P.CODEMP = '20' OR P.CODEMP IS NULL)

Pues resulta que esta consulta no me muestra el registro de la tabla
máquina. Si en cambio, añado en la clausula ON la unión de los campos


CODEMP
de ambas tablas, y quito el último AND de la clausula WHERE, la consulta


se
comporta como es de esperar. Devuelve todos los datos de la tabla


máquinas, y
con valor NULL, los campos correspondientes a la tabla Pólizas.
Entiendo que la sintaxis correcta para esta consulta es como os acabo


de
contar, especificando en la clausula ON todos los campos que conforme la
clave principal en la tabla de la izquierda. Pero por otros motivos,
necesitamos montar la consulta de esta manera.

Pues bueno, despues de todo el tostón, alguien podría decirme porque se
comporta asi? No debería ser lo mismo igualar los campos clave en el


apartado
ON, que filtrar luego los valores posibles de los campos en el apartado


WHERE?

Muchas Gracias a TODOS, por haber leido hasta aqui ;)
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida