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

Listado completo con relación 1:n

Estas en el tema de Listado completo con relación 1:n en el foro de Mysql en Foros del Web. Tengo dos tablas: usuario (id, nombre) datos_usuario (id, usuarioId, nombre_dato, valor_dato) Un usuario puede tener n datos de usuario (1:n) Necesito sacar un listado en ...
  #1 (permalink)  
Antiguo 08/10/2013, 12:01
 
Fecha de Ingreso: febrero-2008
Ubicación: Madrid
Mensajes: 474
Antigüedad: 16 años, 3 meses
Puntos: 1
Exclamación Listado completo con relación 1:n

Tengo dos tablas:

usuario (id, nombre)

datos_usuario
(id, usuarioId, nombre_dato, valor_dato)

Un usuario puede tener n datos de usuario (1:n)


Necesito sacar un listado en las que las columnas son los nombre_dato (todos) y las filas son el nombre del usuario y sus valor_dato correspondientes. A ser posible en una consulta pero no es imprescindible. No se me ocurre la consulta.

Gracias.
  #2 (permalink)  
Antiguo 08/10/2013, 12:11
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Listado completo con relación 1:n

Es una consulta de manual. Se usa un INNER JOIN, simplemente.
Código MySQL:
Ver original
  1. SELECT a, b, c, d, ...
  2. FROM tabla1 T1 INNER JOIN tabla2 T2 ON T1.id_tabla1 = T2.id_tabla1
donde T1.id_tabla1 es la PK de la tabla1, y T2.id_tabla1 es la FK que apunta a ella.

¿Se entiende bien?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 08/10/2013, 12:18
 
Fecha de Ingreso: febrero-2008
Ubicación: Madrid
Mensajes: 474
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: Listado completo con relación 1:n

No es tan sencillo, desconozco los campos de la tabla datos_usuario, solo puedo ir por el usuario.

Espero haberme explicado.

Última edición por jorgegetafe; 08/10/2013 a las 12:26
  #4 (permalink)  
Antiguo 08/10/2013, 12:40
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Listado completo con relación 1:n

El principio es el mismo, además, tu mismo nos estas diciendo cómo es esa tabla, y de esa descripción se infiere la relación:
Cita:
usuario (id, nombre)
datos_usuario(id, usuarioId, nombre_dato, valor_dato)
Si esa descripción es correcta, entonces ya tienes la forma....
¿Entiendes cómo funciona el INNER JOIN, o el problema es que no conoces nada de SQL?
__________________
¿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 08/10/2013, 12:58
 
Fecha de Ingreso: febrero-2008
Ubicación: Madrid
Mensajes: 474
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: Listado completo con relación 1:n

Conozco inner join y sql tambien, veo que me explico fatal. Me gustaría sacar una consulta con:

columnas: El nombre de TODOS los diferentes datos_usuario (datos_usuario.nombre_dato)

filas: En cada fila, el nombre del usuario y todos los datos_usuario correspondientes (aunque no tenga ninguno de ellos).

Solo debe salir una fila por usuario, algo tal que así (lo siento, no se ponerlo en una tabla como dios manda):

______Provincia ______pais ______telefono
pedro __ madrid________españa____234234
juan____null__________francia_____null
javier___null__________null________null
paco____madrid_______null________2342342

Desconozco los datos_usuario.nombre_dato (esos datos serán metidos por terceros)

Gracias.

Última edición por jorgegetafe; 08/10/2013 a las 13:12
  #6 (permalink)  
Antiguo 08/10/2013, 13:23
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Listado completo con relación 1:n

OK, Ahora se entiende mejor...
Lo que quieres es la lista completa de personas, se tengan o no detalles.

Eso sería un LEFT JOIN, pero el problema que le veo es que no tienes una tabla normalizada. La tabla de datos_usuario, en principio, es una tabla de tipo taxonómica, aparentemente diseñada con el mismo aspecto de las de Wordpress. Ese tipo de tablas no sirve para ser usadas en consultas como las que planteas, porque no se ajustan al modelo relacional.
Para que se entienda un poco mejor: Esas tablas son "bolsas de datos", donde se agrupan todas las cosas sin respetar dominios, y como no se tiene una limitación de las tipologías de datos (campo nombre_dato), no se puede establecer cuántos INNER JOIN se deben indicar, ni cual será el parámetro de cada uno.

La recuperación de datos de esa clase se hace por una combinación entre SQL y programación. Pero no medio de SQL puro.
Se puede intentar una query que devuelva esas tres columnas de datos, pero no será sencillo:
Código MySQL:
Ver original
  1. SELECT u.id, u.nombre, d.Provincia, d.ciudad, d.telefono
  2. FROM usuario u LEFT JOIN
  3.     (SELECT d1.usuarioid, d1.valor_dato Provincia, d2.valor_dato ciudad, d3.valor_dato telefono
  4.        FROM datos_usuario d1
  5.             INNER JOIN datos_usuario d2 ON d1.usuarioId = d2.usuarioId
  6.             INNER JOIN datos_usuario d2 ON d1.usuarioId = d3.usuarioId
  7.       WHERE d1.nombre_dato = 'provincia' AND d2.nombre_dato = 'ciudad' AND d3.nombre_dato = 'telefono') d ON u.id = d.usuarioid;
Por cada columna extra, la tabla derivada deberá incluir otro nivel de INNER JOIN, con su respectivo parámetro de nombre_dato.

Como verás, se complica bastante.

En realidad el problema es que la tabla datos_usuario debería tener una columna por cada atributo de detalle que exista. Eso es lo que debería existir, y no esa "bolsa de datos".
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 08/10/2013, 13:39
 
Fecha de Ingreso: febrero-2008
Ubicación: Madrid
Mensajes: 474
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: Listado completo con relación 1:n

Vale, esa era la idea que tenía, que no se puede hacer puramente con sql, más que nada porque no puedo hacer el siguiente select:
Código:
SELECT u.id, u.nombre, d.Provincia, d.ciudad, d.telefono 
porque como he comentado, no conozco los datos_usuario.

Había pensado realizar una consulta como esta:

Código:
select du.nombre,
(select nombre from usuario u where u.id = du.usuario_id) nombre
from datos_usuario du
y luego mediante programación, con algún tipo de objeto/s ir montando todo en memoria por usuario, pero el problema es la ordenación de los datos, hacer una ordenación por varios campos en java va a ser un parto durísimo/imposible.
  #8 (permalink)  
Antiguo 08/10/2013, 13:58
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Listado completo con relación 1:n

En realidad me parece que estás complicándote.
Lo primero que debes hacer es:
Código MySQL:
Ver original
  1. SELECT DISTINCT nombre_dato
  2. FROM datos_usuarios;
y luego, con lo obtenido, construyes la query dinámicamente, para recuperar cada columna de datos de cada usuario.
Eso, siempre y cuando no haya basura entre los datos, como por ejemplo que hayan puesto "provincia", "pcia." y "prov", por ejemplo. De suceder eso, primero deberás manipular esa tabla para normalizar los datos-basura que haya.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: completo, listado, tabla
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 20:19.