Autor
|
Tema: [resuelto] imprimir lista con datos de db (Leído 3,070 veces)
|
gAb1
Desconectado
Mensajes: 731
|
Hola buenas! Estoy haciendo una lista que imprima informacion de varias tablas de una base de datos mysql. Estas son las tablas: - account_type: tiene dos columnas: type (varchar, usada en la consulta) y bonus (int, imprimida en la lista). - friends: de aqui necesito las columnas total y cashed_month1-12 (todas int) - members: varias columnas: id y acc_type (usadas en la consulta), las demás columnas tambien son seleccionadas y se deberían de imprimir normal. Lo que el siguiente script debería hacer sería lo siguiente: Seleccionar de estas 3 tablas: friends.*, members.*, y account_type.* pero con la unica condición de INNER JOIN account_type ON account_type.type = members.acc_type if(isset($_GET['id'], $_SESSION['user_id'])) { /* prepare statement */ if ($stmt = $mysqli->prepare("SELECT COUNT(*) rowCount FROM friends WHERE friendID = ? AND userID = ?")) { $stmt->bind_param('ii', $_GET['id'], $_SESSION['user_id']); $stmt->execute(); /* bind variables to prepared statement */ $stmt->bind_result($rowCount); /* fetch values */ if($stmt->fetch()) { if ($rowCount > 0) { $stmt->close(); if ($stmt = $mysqli->prepare("SELECT members.*, account_type.* FROM members INNER JOIN account_type ON account_type.type = members.acc_type WHERE members.acc_type = ?")) { $stmt->bind_param('s', $_SESSION['acc_type']); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_array(); if ($row['status'] == 1) { $status = 'Activa'; } elseif ($row['status'] == 0) { $status = 'No Activa'; } echo '<p>La cuenta esta ' . $status . '; $monthNames = array("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"); $paid = array(); //Placeholder for paid months. for ($i = 1; $i < 13; $i++) { $month = 'month' . $i; $cashed_month = 'cashed_month' . $i; if($row[$month] == 1) { $paid[] = 'Pagado'; $bonus[] = $row['bonus'] . '€'; } else { $paid[] = 'No Pagado'; $bonus[] = 'n/a'; } if ($row[$cashed_month] == 1) { $cashed[] = 'Si'; } elseif ($row[$month] == 1) { $cashed[] = 'No'; } else { $cashed[] = 'n/a'; } } //Now make the HTML list foreach($monthNames as $key => $month) { echo ' <div class="list"> <ul> <li><a class="month">' . $month . '</a></li> <li><a class="status">' . $paid[$key] .'</a></li> <li><a class="bonus">' . $bonus[$key] . '</a></li> <li><a class="cashed">' . $cashed[$key] . '</a></li> </ul> </div>'; } echo '<div class="clear"></div>'; echo '<p>Total recibido para ' . date('Y') . ': ' . $row['total'] . '€</p>'; echo '<a href="/friend">Volver</a>'; } else echo $mysqli->error; } else{ echo $_SESSION['username'], ', no estás autorizado para ver la información de este socio ya que no es tu amigo...'; } } /* close statement */ $stmt->close(); } else echo $mysqli->error; /* close connection */ $mysqli->close(); }
Pero no encuentro la manera de agregar esta tercera tabla sin necesidad de condicion, ya que si hago otro inner join con la tercera tabla, no funciona como es debido: Por ejemplo, necesito trabajar con $row['bonus'] (tabla account_type) pero que sea el del usuario actual, no del otro (friendID). Si ambas cuentas (friendID y userID) tienen el mismo tipo de cuenta (acc_type) todo funciona, pero no todos las cuentas son iguales, entonces si cambio el acc_type del usuario logueado no funciona nada, es como si solamente se muestra información si ambas cuentas tienen el mismo tipo, y eso no debería ser así. Por eso no puedo juntar esta tercera tabla. ¿Es posible selecionar una tabla más sin ninguna condicion? Simplemente cogiendo toda la informacion sin más y en la misma sentencia preparada. Gracias!
|
|
« Última modificación: 7 Octubre 2014, 23:41 pm por gAb1 »
|
En línea
|
|
|
|
MinusFour
|
No debería darte problemas si agregas un INNER JOIN sin ninguna condicion.
Que viene siendo lo mismo que: (en MySQL)
|
|
|
En línea
|
|
|
|
gAb1
Desconectado
Mensajes: 731
|
Actualmente estoy usando INNER JOIN. Entonces para MySQL debo usar CROSS JOIN? Aunque ahora que lo pienso bien creo que necesito condiciones para las columnas y de que ID debo coger cada columna: 1º from members.status (y otras columnas como name, month1-12 and photo) where members.id = $_GET['id'] 2º from account_type.type necesito que compare con members.acc_type pero especificando where members.id = $_SESSION['user_id'] y solo de esa id. 3º from friends.cashed_month1-12 (y la columna total que debería incluirse sin problemas) where friends.friendID = $_GET['id'] Necesito una consulta que haga todo eso, pero mi conocimiento en sql es bastante limitado. He estado intentandolo con: SELECT friends .*, members .*, account_type .* FROM members INNER JOIN friends ON friends .friendID = members .id INNER JOIN account_type ON account_type .type = members .acc_type WHERE friends.friendID = ? AND members.acc_type = ?")) { $stmt->bind_param('is', $_GET['id'], $_SESSION['acc_type'];
Y obviamente no funciona... Edito: se me olvido cambiar el bind_param de otra prueba. Y el problema no era hacer un JOIN para la tercera tabla. Asi que debo hacer un JOIN, pero el problema esque mi consulta esta mal.
|
|
« Última modificación: 7 Octubre 2014, 18:29 pm por gAb1 »
|
En línea
|
|
|
|
MinusFour
|
Sería mejor que describieras que quieres hacer con tus tablas. Tampoco entiendo muy bien tus tablas o sus relaciones. Pon un Describe de las tablas;
|
|
|
En línea
|
|
|
|
gAb1
Desconectado
Mensajes: 731
|
La idea era hacer un sistema RBAC, pero en realidad solo necesito 1 columna para un permiso entonces lo hice asi: account_type -> type y bonus. Cada cuenta puede ser de un tipo u otro, por lo que en la tabla miembros tengo una columna llamada acc_type que coincide con el valor de account_type.type, entonces la cuenta tiene los privilegios de ese tipo. Y las columnas month1 a 12, 1 quiere decir si ha pagado ese mes y 0 que no lo ha pagado. Tambien cada cuenta tiene un status, 1 activa y 0 no activa. La tabla friends tiene el id de la cuenta que es amiga de otra cuenta (friendID es amigo de UserID) las otras columnas, total: el total acumulado para userID y cashed_month1 a 12, 1: ha recibido el bonus para ese mes y 0: no no lo ha recibido, tambien para userID Nunca he hecho eso de DESCRIBE, no se que es. Lo que no entiendo es porque INNER JOIN account_type ON account_type.TYPE = members.acc_type WHERE members.acc_type = $_SESSION['acc_type']
no funciona si $_GET['id'] (friendID) no tiene el mismo tipo de cuenta.... ¿Ves alguna relación entre members.acc_type (de la cuenta logueada) con members.acc_type (friendID)? Es muy extraño la verdad, debe ser esa consulta que esta mal hecha, pero no veo cual es el fallo... Si no coinciden ambas devuelve NULL Así es como lo tengo ahora: if ($stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.* FROM members INNER JOIN friends ON friends.friendID = members.id INNER JOIN account_type ON account_type.type = members.acc_type WHERE friends.friendID = ? AND members.acc_type = ?")) { $stmt->bind_param('is', $_GET['id'], $_SESSION['acc_type']);
¿Tal vez si uso LEFT o RIGHT devolverá todo lo demás menos el match entre los dos ids?
|
|
« Última modificación: 7 Octubre 2014, 19:14 pm por gAb1 »
|
En línea
|
|
|
|
MinusFour
|
Yo la verdad es que no tengo ni idea de como es tu base de datos. Es muy ambigua tu descripcion (al menos para mi).
Si no puedes pegar el describe, entonces pon la estructura de tu base de datos.
|
|
|
En línea
|
|
|
|
|
MinusFour
|
Vamos por partes: SELECT members. *, account_type. * INNER JOIN account_type ON `members`. `acc_type` = `account_type`. `type`
Debería regresar un join 1 a 1 con el account_type de members para obtener el bonus (me imagino). Ahora para la tabla friends, no estoy muy seguro de la estructura de la tabla, pero quiero creer que hay varios friendId para userId. Entonces, si haces un inner join con friends por userid: SELECT members. *, account_type. *, friends. * INNER JOIN account_type ON `members`. `acc_type` = `account_type`. `type`
Te debería devolver todos los registros unidos con todos los friends por ejemplo: John - Mike John - Joe John - Mark John - Luke Entonces, el resultado quedaria como: John [columnas de members] [columnas de account_type] Mike [columnas de friend] John [columnas de members] [columnas de account_type] Joe [columnas de friend] John [columnas de members] [columnas de account_type] Mark [columnas de friend] John [columnas de members] [columnas de account_type] Luke [columnas de friend] Las columnas de account_type estan ligadas a la informacion de John, no de Mike, Joe, Mark o Luke. Ahora lo que puedes hacer para traerte la informacion relevante de Mike, Joe, Mark y Luke es hacer otro inner join. SELECT members. *, account_type. *, friends. *, membersF. * INNER JOIN account_type ON `members`. `acc_type` = `account_type`. `type`
Esto me devuelve la informacion del amigo en membersF.* ahora si necesitas sacar el bonus por account_type: SELECT members. *, account_type. *, friends. *, membersF. *, acctypeF. * INNER JOIN account_type ON `members`. `acc_type` = `account_type`. `type` INNER JOIN account_type AS acctypeF ON `membersF`. `acc_type` = `acctypeF`. `type`
Y los datos ahi estan en acctypeF.* En este caso tienes que tener cuidado con los * y fetch_assoc porque members, membersF y account_type, acctypeF tienen los mismos campos.
|
|
|
En línea
|
|
|
|
gAb1
Desconectado
Mensajes: 731
|
Vale, eso tiene mucho más sentido Solo una cosa, la idea es sacar la informacion del amigo que el usuario haga click, no de todos a la vez. Al principio del archivo .php tengo un script para imprimir la lista de amigos del usuario: // imprimir lista de amigos }
Ahí si que hago: SELECT members.*, friends.* FROM friends INNER JOIN members ON members.id = friends.friendID WHERE friends.userID = ? /* mi id $_SESSION */
Y con eso hago una lista con todos los amigos, y en el nombre imprimido añado un url que envia a la misma página pero con el id del amigo: echo ' <div class="list"> <ul> <li><a class="name" href="friend?id=' . $row['id'] . '">'.$row['name'].'</a></li> <li><a class="subscription">' . $status . '</a></li> <li><a class="totalbonus">' . $row['total'] . '€</a></li> </ul> </div> ';
Entonces ahora estoy atascado en el if que obtiene $_GET['id'] y muestra otra tabla con la información del amigo, y ese es el código que pegué en el primer mensaje, en la misma pagina.php se muestra la lista de amigos y en el nombre hay un link que muestra la información de ese usuario. No estoy seguro pero voy a probar con SELECT members.*, account_type.*, friends.*, membersF.* FROM members INNER JOIN account_type ON `members`.`acc_type` = `account_type`.`type` INNER JOIN friends ON friends.userID = members.id INNER JOIN members AS membersF ON membersF.id = friends.friendID WHERE `members`.`acc_type` = $_SESSION['acc_type'] AND friends.userID = $_SESSION['user_id'] AND membersF.id = $_GET['id']
1º Devolverá el tipo de cuenta para el usuario conectado y así poder obtener el bonus del usuario conectado solo. 2º Aquí ¿devolverá las columnas total y cashed_month1 a 12? para saber si ya ha recibido el bonus de cada mes o no. 3º Aquí devolverá la información relevante para el amigo. Más o menos me voy enterando de como funciona. Lo que no me queda claro es WHERE <-- aquí que tengo que poner? la tabla.columna antes del = o de despues? Gracias! Edito: Funciona perfecto! Muchas gracias ^^
|
|
« Última modificación: 7 Octubre 2014, 23:41 pm por gAb1 »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
como imprimir la lista de cd de formato mp3
Software
|
chicharron
|
1
|
2,324
|
25 Noviembre 2004, 02:34 am
por kyokorn
|
|
|
Problemas con imprimir un arbol binario de busqueda junto a una lista simple!!
Programación C/C++
|
01munrra
|
1
|
5,344
|
23 Junio 2011, 02:24 am
por BlackZeroX
|
|
|
elimiar datos de una lista de base de datos
PHP
|
charles babbage
|
4
|
2,851
|
4 Octubre 2012, 19:51 pm
por arodriguez
|
|
|
Cómo imprimir una lista de vectores
Java
|
reygecko
|
1
|
2,030
|
8 Enero 2013, 13:06 pm
por reygecko
|
|
|
Imprimir una lista enlazada de forma ascendente
Programación C/C++
|
maunk
|
1
|
4,408
|
3 Febrero 2014, 09:29 am
por eferion
|
|