Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Mostrar registros no correspondidos

Estas en el tema de Mostrar registros no correspondidos en el foro de Mysql en Foros del Web. Utilizo MySQL y tengo la siguiente duda: La siguiente instrucción muestra todos los empleados y su departamento, Se incluyen todos los empleados, tengan o no ...
  #1 (permalink)  
Antiguo 13/06/2013, 15:04
 
Fecha de Ingreso: enero-2002
Mensajes: 1.174
Antigüedad: 22 años, 10 meses
Puntos: 21
Mostrar registros no correspondidos

Utilizo MySQL y tengo la siguiente duda:

La siguiente instrucción muestra todos los empleados y su departamento,
Se incluyen todos los empleados, tengan o no departamento asignado.

Código MySQL:
Ver original
  1. select * from empleados a
  2. inner join departamentos b on a.id_departamento=b.id

¿Como una una instrucción para mostrar solo empleados que no tienen asignado departamento?

Gracias.

(Anteriormente por error publiqué mi mensaje en foro equivocado, disculpa anticipada)
  #2 (permalink)  
Antiguo 13/06/2013, 15:25
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 10 meses
Puntos: 447
Respuesta: Mostrar registros no correspondidos

Hola Bier:

No nos dices cuál es la estructura de tus tablas por lo que resulta algo complicado ayudarte...

Jugando un poco al adivino, puedo suponer que el campo id_departamento de tu tabla empleados hace referencia al departamento asignado... aquí habría que preguntar, si es una llave foranea, entonces NO HAY MANERA QUE EL EMPLEADO NO TENGA ASIGNADO UN DEPARTAMENTO... ahora bien, si el campo NO ES LLAVE FORÁNEA y puede tener valores nulos, o valores que no existan en tu tabla DEPARTAMENTOS, entonces el problema es que TIENES UN TERRIBLE MODELO DE BASE DE DATOS.

Uno de mis maestros me dijo hace tiempo: Una Base de Datos sin Integridad Referencial es simplemente un montón de basura almacenada en tablas... así de claro.

Dime, cuál es la lógica acerca de la asignación de departamento a los usuarios.

- ¿Un usuario puede o no puede tener asignado un departamento?. Si la respuesta es sí, entonces el campo ID_DEPARTAMENTO NO DEBE EXISTIR EN LA TABLA DE EMPLEADOS... deberías tener una tabla intermedia donde agregues sólo aquellos empleados que tienen asignado un departamento.

- ¿Un usuario debe tener asignado siempre un departamento?. Si la respuesta es si, entonces el modelo es correcto, pero entonces tu pregunta es un completo absurdo.

- ¿Es posible que existan departamentos sin empleados asignados? Si, es posible y eso no afectaría para nada el modelo actual o si agregaras una nueva tabla.

Explica un poco mejor cómo tienes tu información y cuál es la lógica de tu negocio y con gusto tratamos de ayudarte.

Saludos
Leo.
  #3 (permalink)  
Antiguo 13/06/2013, 16:02
 
Fecha de Ingreso: enero-2002
Mensajes: 1.174
Antigüedad: 22 años, 10 meses
Puntos: 21
Respuesta: Mostrar registros no correspondidos

Hola leonardo_josue,

Gracias por tus comentarios.
1.- Respecto a los campos de las tablas, en la consulta que puse se aprecian, lo mostraré de otra forma, espero sea más clara.

2.- Puse un ejemplo lo más simple posible, solo 2 tablas y un campo en cada tabla.

3.- Es solo un supuesto de tablas, y lo que busco es la respuesta a la pregunta planteada, no tanto si mi aplicación ha sido correctamente diseñada.

4.- En mi caso real, se trata de un catálogo de artículos y deseo saber ha tenido, o no, movimientos registrados, ya que puedo tener artículos en el catálogo y no necesariamente tener movimientos.

Tabla de empleados:
Código MySQL:
Ver original
  1. idEmpleado int(3)
  2. id_departamento int(3)
  3. Nombre char(30)

Tabla de departamentos:
Código MySQL:
Ver original
  1. idDepartamento int(3)
  2. Nombre char(30)

Mi pregunta es:
¿Como puede ser una instrucción para mostrar solo empleados que no tienen asignado departamento?

PS: No veo necesario explicar mi aplicación, solo saber como puede ser una instrucción para ello. Lo puedo resolver con dos instrucciones, pero deseo saber si es posible resolverlo con una sola.

Gracias nuevamente.





Cita:
Iniciado por leonardo_josue Ver Mensaje
Hola Bier:

No nos dices cuál es la estructura de tus tablas por lo que resulta algo complicado ayudarte...

Jugando un poco al adivino, puedo suponer que el campo id_departamento de tu tabla empleados hace referencia al departamento asignado... aquí habría que preguntar, si es una llave foranea, entonces NO HAY MANERA QUE EL EMPLEADO NO TENGA ASIGNADO UN DEPARTAMENTO... ahora bien, si el campo NO ES LLAVE FORÁNEA y puede tener valores nulos, o valores que no existan en tu tabla DEPARTAMENTOS, entonces el problema es que TIENES UN TERRIBLE MODELO DE BASE DE DATOS.

Uno de mis maestros me dijo hace tiempo: Una Base de Datos sin Integridad Referencial es simplemente un montón de basura almacenada en tablas... así de claro.

Dime, cuál es la lógica acerca de la asignación de departamento a los usuarios.

- ¿Un usuario puede o no puede tener asignado un departamento?. Si la respuesta es sí, entonces el campo ID_DEPARTAMENTO NO DEBE EXISTIR EN LA TABLA DE EMPLEADOS... deberías tener una tabla intermedia donde agregues sólo aquellos empleados que tienen asignado un departamento.

- ¿Un usuario debe tener asignado siempre un departamento?. Si la respuesta es si, entonces el modelo es correcto, pero entonces tu pregunta es un completo absurdo.

- ¿Es posible que existan departamentos sin empleados asignados? Si, es posible y eso no afectaría para nada el modelo actual o si agregaras una nueva tabla.

Explica un poco mejor cómo tienes tu información y cuál es la lógica de tu negocio y con gusto tratamos de ayudarte.

Saludos
Leo.
  #4 (permalink)  
Antiguo 13/06/2013, 20:47
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Mostrar registros no correspondidos

Técnicamente no es imposible hacerlo. Es un modelo de casos bastante común en muchos ejercicios, pero no se puede usar INNER JOIN para eso.
Código MySQL:
Ver original
  1. FROM empleados a LEFT JOIN departamentos b ON a.id_departamento = b.id
Respecto a la integridad referencial que te marca Leo, el caso es simple: SI ese campo empleados.id_departamento es NOT NULL, el dato es mandatorio y debe si o si tener un valor que exista en la tabla departamentos. Para que te funcione debe ser nulable.
Ahora bien, desde el punto de vista del análisis de sistemas, tu planteo es absurdo: No puede existir jamas un empleado sin asignar a un departamento, dentro de ninguna organización.
Pero... es tu sistema. Si lo quieres absurdo, estás en tu derecho.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 13/06/2013, 21:10
 
Fecha de Ingreso: enero-2002
Mensajes: 1.174
Antigüedad: 22 años, 10 meses
Puntos: 21
Respuesta: Mostrar registros no correspondidos

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Técnicamente no es imposible hacerlo. Es un modelo de casos bastante común en muchos ejercicios, pero no se puede usar INNER JOIN para eso.
Código MySQL:
Ver original
  1. FROM empleados a LEFT JOIN departamentos b ON a.id_departamento = b.id

Gracias gnzsoloyo
Respecto a la integridad referencial que te marca Leo, el caso es simple: SI ese campo empleados.id_departamento es NOT NULL, el dato es mandatorio y debe si o si tener un valor que exista en la tabla departamentos. Para que te funcione debe ser nulable.
Ahora bien, desde el punto de vista del análisis de sistemas, tu planteo es absurdo: No puede existir jamas un empleado sin asignar a un departamento, dentro de ninguna organización.
Pero... es tu sistema. Si lo quieres absurdo, estás en tu derecho.
Muchas gracias por tu respuesta, me ayuda mucho y lo voy a explorar.

Respecto a tu aseveración de lo absurdo, entiendo tu comentario. Mi planteamiento es solo para ejemplificar la necesidad, pero es aplicable a muchos otros casos, por ejemplo:
  1. Tener una tabla de artículos y una tabla de entradas y salidas, es posible que determinados artículos no hayan tenido movimiento.
  2. Tener una tabla de empleados y una tabla de días con asistencia, es posible que determinados empleados no hayan tenido asistencia.
  3. etc.

Salí regañado, en este caso es un planteamiento de ejemplo, no es un sistema en si.

Gracias nuevamente.
  #6 (permalink)  
Antiguo 13/06/2013, 21:36
 
Fecha de Ingreso: agosto-2003
Mensajes: 174
Antigüedad: 21 años, 3 meses
Puntos: 3
Respuesta: Mostrar registros no correspondidos

Hola

Tu pusiste esto
Código:
    SELECT * FROM empleados a
    INNER JOIN departamentos b on a.id_departamento=b.id
Pero si en vez de esto lo pones así
Código:
    SELECT * FROM empleados a
    LEFT JOIN departamentos b on a.id_departamento=b.id
Ahora sacas todos los de la izquierda (empleados) tengan o no departamento

Y si a eso le ponemos una condición de que se incluyan solo los que tenga b.id=0
Código:
    SELECT * FROM empleados a
    LEFT JOIN departamentos b on a.id_departamento=b.id
    WHERE b.id=0
Te quedan solo aquellos empleados que no tienen departamento.

Si lo que quisieras fuera los departamentos que no tienen empleado sería
Código:
    SELECT * FROM empleados a
    RIGHT JOIN departamentos b on a.id_departamento=b.id
    WHERE a.id=0
  #7 (permalink)  
Antiguo 13/06/2013, 23:16
 
Fecha de Ingreso: enero-2002
Mensajes: 1.174
Antigüedad: 22 años, 10 meses
Puntos: 21
Respuesta: Mostrar registros no correspondidos

Estimado Gedeon,

Más claro no se podría haber expresado. Gracias.
Mi aplicación realmente requiere un aumento en su complejidad, lo estaré resolviendo con MySQL y luego haré una selección con PHP.

Gracias nuevamente.
  #8 (permalink)  
Antiguo 14/06/2013, 03:24
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Mostrar registros no correspondidos

Cita:
Tener una tabla de empleados y una tabla de días con asistencia, es posible que determinados empleados no hayan tenido asistencia.
Es que esto no es lo mismo que decir que no tienen departamento asignado.
Si hubieses planteado esta relación, nadie te hubiese objetado nada, y te habríamos dado la respuesta inmediatamente, que es sencilla.
Una cosa que te voy a hacer notar es que lo que te ha dado Gedeon, es básicamente lo mismo que te doy yo, con una diferencia: Lo que te propone Gedeon no produce resultados, porque en un LEFT JOIN el valor devuelto en la segunda tabla no es cero. Es NULL.

Y NULL no es un cero. NULL no es un dato evaluable con operadores lógicos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 14/06/2013, 04:52
 
Fecha de Ingreso: agosto-2003
Mensajes: 174
Antigüedad: 21 años, 3 meses
Puntos: 3
Respuesta: Mostrar registros no correspondidos

Cita:
Una cosa que te voy a hacer notar es que lo que te ha dado Gedeon, es básicamente lo mismo que te doy yo, con una diferencia: Lo que te propone Gedeon no produce resultados, porque en un LEFT JOIN el valor devuelto en la segunda tabla no es cero. Es NULL.

Y NULL no es un cero. NULL no es un dato evaluable con operadores lógicos.
Tienes razón.

En lo del null también. De puro obvio lo puse sin pensar y esa consulta no dará resultados porque en este caso si el empleado no tiene departamento su id no será cero sino null. Por esta razón no habría que poner la condición de si id es cero sino de si id es null. Yo estaba mas interesado en explicar lo del left y el right y no pensé en lo otro. Disculpas.

Código:
SELECT * FROM empleados a
    LEFT JOIN departamentos b on a.id_departamento=b.id
    WHERE isnull(b.id)
Y de hecho como para relacionarlas a.id_departamento tiene que ser igual a b.id y además buscamos los que b.id sea null basta con mirar a.id_departamento

Código:
select * from empleados where isnull(id_departamento)
Total si de la tabla departamentos no quieres sacar nada en ese caso porque no hay nada.
  #10 (permalink)  
Antiguo 14/06/2013, 05:14
 
Fecha de Ingreso: enero-2002
Mensajes: 1.174
Antigüedad: 22 años, 10 meses
Puntos: 21
Respuesta: Mostrar registros no correspondidos

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Es que esto no es lo mismo que decir que no tienen departamento asignado.
Si hubieses planteado esta relación, nadie te hubiese objetado nada, y te habríamos dado la respuesta inmediatamente, que es sencilla.
Una cosa que te voy a hacer notar es que lo que te ha dado Gedeon, es básicamente lo mismo que te doy yo, con una diferencia: Lo que te propone Gedeon no produce resultados, porque en un LEFT JOIN el valor devuelto en la segunda tabla no es cero. Es NULL.

Y NULL no es un cero. NULL no es un dato evaluable con operadores lógicos.
Gracias por tu explicación.
Realmente lo que deseaba preguntar era una respuesta a la necesidad planteada.
Que si son departamentos, artículos, etc. o analizar si es correcto el diseño no era mi pregunta, entiendo que en otros casos, pueda ser importante una respuesta como la que has expresado.
Gracias

Etiquetas: join, registros, select, sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:57.