Ver Mensaje Individual
  #2 (permalink)  
Antiguo 08/12/2011, 08:51
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, 3 meses
Puntos: 2658
Respuesta: Cómo consigo esto?

Tal y como están armadas las tablas, resulta en consultas algo complicadas como la que has planteado, y con una tendencia a generar productos cartesianos. El problema básico es que, a menos que se trate de un ejercicio de la asignatura Bases de Datos, el modelo planteado en dos tablas no sólo es ineficiente, no respeta el paradigma E-R.
Me explico: Estás atomizando una entidad que define a una persona, pero al hacerlo estás separando atributos que le son propios en una tabla secundaria, donde estás mezclando atributos de diferentes clases de dominio. Eso es incorrecto.
Si la persona siempre tendrá ojos, pelo y piel, esos atributos no se deben separar de la entidad que representa a la misma. Son propiedades de la clase o entidad.
Lo que si puedes hacer es crear una entidad distinta que permita manejar una clasificación para un atributo determinado, especialmente cuando ese atributo sólo contenga un numero acotado de variaciones posible, como es el caso del color de ojos, del color de piel o del tipo y color de pelo.
Además, y principalmente, con ello evitas la repetición de valores en el registro, y la posibilidad de errores de tipeo al ingresar valores similares. Tu esquema, por ejemplo, no previene que se ingrese ("Pelo", "Azul") o bien ("Ojos", "Azles"), por ejemplo.
Si separas esas instancias en tablas diferentes donde cada cosa sea única, el JOIN necesario para crear tu consulta será mucho más sencillo.
En otras palabras:
La tabla 1 debería tener por atributos: (nombre, altura, cabello_id, piel_id, ojos_id, otros_rasgos_id)
La tabla 2 debería ser descompuesta en entidades base, tales como Cabello(cabello_id, desc_color); Ojos(ojos_id, desc_color) y Otros_Rasgos(otros_rasgos_id, descripcion);
La altura no es necesario hacerlo por dos razones: 1) Todo ser tiene una altura física, por lo tanto no es algo opcional o nulificable; 2) No existen rangos acotados, por lo que poner todas las alturas posible requeriría más espacio de disco que la cantidad de personas en la primera tabla.
En ese contexto, crear la sentencia de consulta sería bastante simple:
Código MySQL:
Ver original
  1. SELECT Nif, Nombre,  C.altura, C.desc_color Cabello, O.desc_color, GROUP_CONCAT(R.descripcion) Otros
  2.     tabla1 P
  3.     LEFT JOIN Cabello C ON P.cabello_id = C.cabello_id
  4.     LEFT JOIN Ojos O ON P.ojos_id = O.ojos_id
  5.     LEFT JOIN Otros_Rasgos R ON P.otros_rasgos_id = R.otros_rasgos_id
  6. GROUP BY P.Nif;

Ahora bien, si aún así insistes en usar tu esquema, la idea más aproximada sería:
Código MySQL:
Ver original
  1.     Nif,
  2.     Nombre,
  3.     CONCAT(T1.Rasgo, ' ', T1.Tipo) Pelo,
  4.     CONCAT(T2.Rasgo, ' ', T2.Tipo) Ojos,
  5.     CONCAT(T3.Rasgo, ' ', T3.Tipo) Altura,
  6.     GROUP_CONCAT(CONCAT(T4.Rasgo, ' ', T4.Tipo)) Especial
  7.     tabla1 T
  8.     LEFT JOIN tabla2 T1 ON tabla1.Nif = T1.Nif
  9.     LEFT JOIN tabla2 T2 ON tabla1.Nif = T2.Nif
  10.     LEFT JOIN tabla2 T3 ON tabla1.Nif = T3.Nif
  11.     LEFT JOIN tabla2 T4 ON tabla1.Nif = T4.Nif
  12.     T1.Rasgo ='Pelo'
  13.     OR
  14.     T2.Rasgo = 'Ojos'
  15.     OR
  16.     T3.Rasgo = 'Altura'
  17.     OR
  18.     T4.Rasgo = 'Especial'
  19. GROUP BY T.Nif;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)