Tema: Varios join
Ver Mensaje Individual
  #3 (permalink)  
Antiguo 02/12/2011, 20:43
Avatar de gnzsoloyo
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: Varios join

Es que el hecho de que estés usando dos tablas para lo que deberías usar cuatro, dificulta la cosa.
Me explico: En un modelo desarrollado sobre la base del paradigma E-R, no puedes mezclar entidades que representan cosas distintas, como so Usuarios, Clientes y Contactos. Cada una de ellas debería ser una entidad separada ya que los atributos de cada una suelen ser diferentes, más allá de compartir un conjunto de ellos.
Lo que suele hacerse para evitar problemas es crear una Entidad Persona, de la que dependan las tres en cuestión. A su vez, estas tres tienen entre si relaciones N:N que definirían dos tablas mas, por lo que el esquema debería ser de al menos seis tablas.
Tamaña atomización puede parecerte excesiva, pero el resultado de eso es una escritura mucho más simple de las consultas, un mejor aprovechamiento del espacio de almacenamiento, y la consistencia de no sumar caballos con manzanas.

En cualquier caso, es posible hacer lo que pides con las tablas como las tienes, pero hace que las consultas sean algo complicadas...

Por lo pronto, tienes que definir el razonamiento en forma escalar. Primero crea las consultas que recuperan los bloques a usar, y luego realiza la integración.
Al como:
- Obtener los Usuarios y Clientes:
Código MySQL:
Ver original
  1. SELECT DISTINCT u.*, au.id_usuario id_contacto
  2. FROM usuarios u INNER JOIN a_usuarios au ON u.id_usuario = au.id_usuario
  3. WHERE u.id_ucat = 'Usuario' AND au.id_ucat = 'Cliente';
- Obtener los Clientes y Contactos:
Código MySQL:
Ver original
  1. SELECT DISTINCT u.*, au.id_usuario id_contacto
  2. FROM usuarios u INNER JOIN a_usuarios au ON u.id_usuario = au.id_usuario
  3. WHERE u.id_ucat = 'Cliente' AND au.id_ucat = 'Contacto';
- Obtener los Usuarios y Contactos:
Código MySQL:
Ver original
  1. SELECT DISTINCT u.*, au.id_usuario id_contacto
  2. FROM usuarios u INNER JOIN a_usuarios au ON u.id_usuario = au.id_usuario
  3. WHERE u.id_ucat = 'Usuario' AND au.id_ucat = 'Contacto';
El problema se complica a la hora de integrar estas tres en una sola, algo más elaborada...

Esta es sólo una aproximación, puede que no te de el resultado esperado porque no tengo como verificarla:
Código MySQL:
Ver original
  1. SELECT DISTINCT u.*, au.id_usuario id_contacto
  2. FROM usuarios u INNER JOIN a_usuarios au ON u.id_usuario = au.id_usuario
  3. WHERE u.id_ucat = 'Usuario' AND au.id_ucat = 'Contacto')
  4. SELECT TC.id_usuario, TC.apellido_empresa, TC.id_contacto
  5.   (SELECT DISTINCT u.*, au.id_usuario id_cliente
  6.   FROM usuarios u INNER JOIN a_usuarios au ON u.id_usuario = au.id_usuario
  7.   WHERE u.id_ucat = 'Usuario' AND au.id_ucat = 'Cliente') T3
  8.   (SELECT DISTINCT au.id_usuario id_contacto
  9.   FROM usuarios u INNER JOIN a_usuarios au ON u.id_usuario = au.id_usuario
  10.   WHERE u.id_ucat = 'Cliente' AND au.id_ucat = 'Contacto') T4 ON T3.id_cliente = T4.id_contacto) TC;

Para que puedas apreciar la diferencia, esto sería un ejemplo de consulta usando un esquema como el que te describía más arriba:
Código MySQL:
Ver original
  1. SELECT U.id_usuario, U.apellido_empresa, C.id_contacto
  2. FROM Usuarios U
  3.      INNER JOIN usuarios_contactos UC USING(id_usuario)
  4.      INNER JOIN contactos C USING(id_contacto)
  5. SELECT U.id_usuario, U.apellido_empresa, C.id_contacto
  6. FROM Usuarios U
  7.      INNER JOIN usuarios_clientes UC USING(id_usuario)
  8.      INNER JOIN clientes_contactos CC USING(id_cliente)
  9.      INNER JOIN contactos C USING(id_contacto);

¿Se aprecia la simplicidad?

A veces lo que parece darnos cosas fáciles de programar, en realidad nos complica la vida a largo plazo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 02/12/2011 a las 20:53