Comunidad de diseño web y desarrollo en internet online

¿Como puedo relacionar tres tablas?

Citar            
MensajeEscrito el 09 Sep 2010 03:31 pm
Hola a todos,

Primero dar las gracias al foro porque he encontrado siempre muchísimas información muy útil para otros problemas que se me han presentado.

Es la primera vez que publico una duda y aunque he explorado muchos de los hilos que hay abiertos, no he encontrado ninguno que se ajuste a mi problema. Espero haber mirado bien.

Pal caso, mi problema es con la relación de 3 tablas en MySQL. Todas tienen relación entre ellas y la salida de datos que yo quiero, tiene que tomar datos de los valores de sus tablas.

Como no me entiendo ni yo mismo al explicarlo, he hecho un pdf con la estructura de lo que necesito y de lo que soy incapaz de hacer que funcione.
[url=http://rapidshare.com/files/418068961/ProblemaMySQL.pdf][/url] (enlace directo, sin esperas)

Cualquier comentario será bienvenido, para que deje de estar perdido... :shock: :shock:

Saludos y muchas gracias por adelantado

Por CLAnonimo

Claber

600 de clabLevel

5 tutoriales
1 articulo

 

Este es un usuario anónimo genérico para las cuentas borradas o perdidas.

firefox
Citar            
MensajeEscrito el 09 Sep 2010 05:48 pm
Creo que empezaría haciendo esta consulta:

Código MySQL :

SELECT `jos_users`.`id`, `jos_users`.`name`, `jos_users`.`email`, `jos_community_fields_values`.`value`,
`jos_community_fields`.`name`
FROM `jos_users`, `jos_community_fields_values`, `jos_community_fields`
WHERE `jos_users`.`id` = `jos_community_fields_values`.`user_id`
AND `jos_community_fields`.`id` = `jos_community_fields_values`.`field_id`

Obtienes esto:

Código :

id   nombre   email   value   name
62   Paco Flor   [email protected]   1975-7-22 23:59:59   Cumpleaños
62   Paco Flor   [email protected]   Calle de Papalopoulus3   Dirección
62   Paco Flor   [email protected]   Testimonial   Nivel
62   Paco Flor   [email protected]   745874321   Teléfono
62   Paco Flor   [email protected]   Madrid   Ciudad
63   Este Banesto   [email protected]   1986-5-25 23:59:59   Cumpleaños
63   Este Banesto   [email protected]   Alar del Rey 4   Dirección
63   Este Banesto   [email protected]   Formativo   Nivel
63   Este Banesto   [email protected]   875412454   Teléfono

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 09 Sep 2010 08:23 pm
Muchísimas gracias DriverOp!

Después de 231.203.876.231 pruebas y horas, conseguí sacar esa misma salida que me has puesto (joder, y sólo 2 horas depués de poner mi post lo tenías)

Llegué hasta ahí, pero soy incapaz de hacer la salida esperada: Hacer que en una misma fila (id) aparezca toda la información buscada... ¿Cómo puedo convertir en título de tabla, un campo dentro de una tabla? Quiero decir, que si id, nombre, email value y name son mis título de tabla, ¿Cómo hacer que también lo sean cumpleaños, dirección, nivel, telefono y ciudad, que son valores dentro de la tabla jos_community_fields? Subselecciones?

Estoy enganchado con esto!
Muchas gracias otra vez!

Un saludo

Por CLAnonimo

Claber

600 de clabLevel

5 tutoriales
1 articulo

 

Este es un usuario anónimo genérico para las cuentas borradas o perdidas.

firefox
Citar            
MensajeEscrito el 10 Sep 2010 01:54 pm
Te entendí desde el primer mensaje lo que quieres hacer, básicamente quieres convertir columnas en una fila, me temo que no es posible hacerlo con MySQL, pero considero que no hace falta tampoco pues la consulta que te dí la puedes manipular con PHP para obtener el resultado que quieres. En este momento no tengo tiempo para ponerte un ejemplo de cómo sería (estoy en la chamba) pero ni bien llegue a mi máquina me pongo en ello (realmente me parece un desafío interesante :P)

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 10 Sep 2010 03:55 pm

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 10 Sep 2010 04:12 pm
Gracias Inyaka!

Efectivamente ya había visto ese material, de hecho fue con lo que fui capaz de hacer algo parecido a lo que me comentó DriverOp en su primera respuesta, pero en ese ejemplo de tu entrada no muestra toda la información de un usuario (o para ser más exactos, en mi torpeza no soy capaz de hacerlo).

Por lo que he estado leyendo por ahí, creo que mi problema va en lo que comenta DriverOp, no tengo claro que sólo con Queris MySQL pueda sacar lo que busco, porque primero tengo que consultar una tabla, quedarme con los datos en una matriz, y luego mostrarla "maquetada" como busco en la tabla final...

DriverOp escribió:

En este momento no tengo tiempo para ponerte un ejemplo de cómo sería (estoy en la chamba) pero ni bien llegue a mi máquina me pongo en ello (realmente me parece un desafío interesante :P)


Sólo faltaba encima que tengas que ir corriendo! Muchas gracias por el esfuerzo... En realidad esto lo hago por poner desafíos a la comunidad, para entretenernos y eso :D :D ^^ ^^

Gracias again!

Por CLAnonimo

Claber

600 de clabLevel

5 tutoriales
1 articulo

 

Este es un usuario anónimo genérico para las cuentas borradas o perdidas.

firefox
Citar            
MensajeEscrito el 10 Sep 2010 04:28 pm
a ser franco es bastante sencillo

tienes que unir las tablas usando JOINS y luego armar lo que quieres mostrar


dime cuales son las 3 tablas y cuales campos se relacionan, mas tarde veo el asunto, por mientras lee bien el tuto ;)

DriverOp esto no es bueno hacerlo:

Código MySQL :

FROM `jos_users`, `jos_community_fields_values`, `jos_community_fields` 


asi no tienes control sobre que campos unen la consulta ni si dejaras fuera los no relacionados.

de todos modos se agradece la intención ;)

¬¬ lee también el tuto

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 10 Sep 2010 04:37 pm
Encima no me digas que es fácil, que me deprimo más todavía!!! Arggggg :-)

He dejado un documento con las tablas, sus estructuras relaciones y salida esperada aquí:

http://rapidshare.com/files/418068961/ProblemaMySQL.pdf

Estoy intentando replicar lo del tutorial, pero a la hora de armar la tabla de salida que yo quiero, no soy capaz de dar con la clave. Me estoy leyendo tu tutorial y también estoy mirando la documentación de MySQL de la función Join, pero no acabo de verlo.

Pero ahora me lo estudio bien, aunque a mi no me parece sencillo!!!!

Por CLAnonimo

Claber

600 de clabLevel

5 tutoriales
1 articulo

 

Este es un usuario anónimo genérico para las cuentas borradas o perdidas.

firefox
Citar            
MensajeEscrito el 10 Sep 2010 05:38 pm
dean:
No es sencillo.
Como he dicho ya, lo que quieres es transponer filas por columnas y eso no es posible usando MySQL.
Bien pues, he llegado a este código que hace lo que pides:

Código PHP :

require("dbutil.inc.php");

$columnas = Array(-1=>"Nombre",0=>"Email"); // Estas columnas están sí o sí, pero no son parte de jos_community_fields

$db = new cDB();
$db->Connect("localhost","test","root","pwdfive5");
if ($db->error) { echo $db->errno.": ".$db->errmsg; exit; }

/* Primero tomo el nombre de las columnas */
$sql = "SELECT `id`, `name` FROM `jos_community_fields` ORDER BY `id`";
$db->Query($sql);
if ($fila = $db->First()) {
   echo "<table><tr>";
   do {
      $columnas[$fila['id']] = $fila['name']; // Aquí agrego a $columnas las columnas a mostrar
   } while ($fila = $db->Next());
   foreach($columnas as $key => $value) {
      echo "<th>".$value."</th>\n";
   }
}

/* Ahora la verdadera consulta */
$sql = "SELECT `jos_users`.`id`, `jos_users`.`name` AS nombre, `jos_users`.`email`, `jos_community_fields_values`.`value`, 
`jos_community_fields`.`name` 
FROM `jos_users`, `jos_community_fields_values`, `jos_community_fields` 
WHERE `jos_users`.`id` = `jos_community_fields_values`.`user_id` 
AND `jos_community_fields`.`id` = `jos_community_fields_values`.`field_id`
ORDER BY `jos_community_fields_values`.`user_id`, `jos_community_fields_values`.`field_id`";
$db->Query($sql);
if ($fila = $db->First()) {
   $currid = -1; // Valor imposible
   do {
      if ($fila['id'] != $currid) { // Si ha cambiado el ID, es otro usuario, por lo tanto otra fila en la tabla.
         echo "<tr><td>".$fila['nombre']."</td><td>".$fila['email']."</td>";
         $currid = $fila['id'];
      }
      echo "<td>".$fila['value']."</td>";
   } while ($fila = $db->Next());
   echo "</table>";
} // if
$db->Disconnect();


Una gran salvedad: he usando mi propia biblioteca de clase para manejar todo lo que tiene que ver con MySQL pero espero entiendas la lógica del código (si quieres la biblioteca, me la pides por mensaje privado y te la paso).

Estoy seguro que el código que te presento se puede mejorar, incluso que haya otra forma de hacer lo que quieres mucho mejor ésta, pero al menos ésta funciona :P

Inyaka escribió:

a ser franco es bastante sencillo

Lamento disentir.

Inyaka escribió:

DriverOp esto no es bueno hacerlo:

Código MySQL :

FROM `jos_users`, `jos_community_fields_values`, `jos_community_fields` 


asi no tienes control sobre que campos unen la consulta ni si dejaras fuera los no relacionados.

No sé de qué estás hablando, la consulta SQL debe saber qué tablas intervienen en la consulta.

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 10 Sep 2010 07:05 pm

DriverOp escribió:

No sé de qué estás hablando, la consulta SQL debe saber qué tablas intervienen en la consulta.


espero que no te sientas atacado pues no es la intención.

si, se sabe que tablas intervienen en la consulta, pero no como se relacionan entre si.

XD dean disculpa haber dicho que era facil no fue mi intención herir tus sentimientos


mira, Jos_community_fields_values es una tabla que relaciona Jos_users con Jos_community_fields a traves de sus campos user_id y field_id
por cierto tu no debes crear nuevas tablas, solo debes consultarlas ;)

acabo de ver los resultados que esperas y a la noche le doy una vuelta ;)

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 10 Sep 2010 08:57 pm
Inyaka:
Sin acritud, sinceramente no sé de qué estás hablando. Yo no estoy creando ninguna tabla, las estoy consultando. Ya sé que Jos_community_fields_values mantiene la relación entre las otras dos tablas, ¿y? :?

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 10 Sep 2010 09:25 pm
DriverOp respira y no te sulfures, la primera parte hiba dedicada a ti , luego le estaba hablando a Dean ;)


¬¬ sigue estudiando ¡¡¡

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 11 Sep 2010 02:58 am
Bien, la consulta resulto un poco mas compleja de lo que esperaba, la verdad, para hacerla mas dinámico tendría que recurrir a procedimientos almacenados, funciones o quizas mandar a la mierda el rendimiento y hacer una subquery, pero encontré una solución bastante óptima desde el punto de vista de rendimiento, aunque poco flexible T_T

mira, si ya sabemos los resultados de la tabla Jos_community_fields simplemente usamos su id de forma dura y unimos varias veces la tabla Jos_community_fields_values a la tabla Jos_users

comunmente no doy resultados pero voy a haccer una excepción dado lo extraña de la consulta ;)

Código MySQL :

 SELECT
u.Nombre,
u.Email,
v1.value F_BIRTHDAY,
v2.value F_DIRECCION,
v3.value F_NIVEL,
v4.value F_TELEFONO,
v5.value F_CIUDAD
FROM Jos_users u
-- si, asi, en duro
INNER JOIN Jos_community_fields_values v1 ON v1.field_id = 1 AND u.id = v1.user_id
INNER JOIN Jos_community_fields_values v2 ON v2.field_id = 2 AND u.id = v2.user_id
INNER JOIN Jos_community_fields_values v3 ON v3.field_id = 3 AND u.id = v3.user_id
INNER JOIN Jos_community_fields_values v4 ON v4.field_id = 4 AND u.id = v4.user_id
INNER JOIN Jos_community_fields_values v5 ON v5.field_id = 5 AND u.id = v5.user_id

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 11 Sep 2010 03:55 am
Joooder!

Brutal! La consulta de MySQL me parece brutal, y que además responde exáctamente a lo que necesito, porque pensándolo bien, no voy a incorporar en los informes mucha más información que la de esos campos, con lo cual tampoco pasa nada por fijar esos campos como has hecho. Muchísimas gracias Inyaka, y gracias por la excepción... me haces un favor impresionante.

He probado el PHP de DriverOp, y también funciona perfectamente (he interpretado tu librería y la he replicado para probar) Con lo cual puedo reutilizarlo en el caso de necesitarlo en páginas externas y demás, así que es genial igualmente.

Muchísimas gracias a los dos, y gracias por la rápida respuesta y vuestro esfuerzo.

Ahora a empoyar para no repetir estos atascos. :-)

Por CLAnonimo

Claber

600 de clabLevel

5 tutoriales
1 articulo

 

Este es un usuario anónimo genérico para las cuentas borradas o perdidas.

firefox
Citar            
MensajeEscrito el 11 Sep 2010 04:19 am
Me alegra de que te halla servido y espero que sigas aprendiendo


PD. bienvenido a cristalab ;)

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 11 Sep 2010 01:42 pm

dean escribió:

Muchísimas gracias a los dos, y gracias por la rápida respuesta y vuestro esfuerzo.

Pues de nada :)

Por DriverOp

Claber

2510 de clabLevel



 

opera

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.