Necesito ayuda con SQL :-)

Iniciado por Brida, 13 Agosto 2013, 04:49 AM

0 Miembros y 1 Visitante están viendo este tema.

Brida

¡Hola a todos y gracias por la ayuda que me puedan aportar!

Os comento, tengo una base de datos que guarda categorías y sub-categorías (categorías dentro de las categorías principales), la tabla es algo así:


IDnombrecategoria_de
1Nuestros Servicios0
2Arreglar ordenadores1
3Reparar móviles1
4Contactar0

* categoría_de = 0; Es la principal



Lo que necesitaría es montar el menú con ul,li pero me han pedido que lo haga con las mínimas consultas posibles.

A mi se me había ocurrido hacer un

SELECT * FROM tabla WHERE categoria_de = 0

Y luego cuando lo recorra volver hacer la consulta con cada uno para ver si tiene sub-categoría, pero estoy seguro que se podrá hacer de alguna otra forma.

¿Cómo lo haríais vosotros/as?

Saludos y gracias por leerme.

#!drvy

Si vas a hacerlo solo de 1 nivel (principal -> submenu) y que no haya mas niveles (principal -> submenu -> submenu) es bastante facil y se puede hacer con una sola consulta.

Teniendo la siguiente estructura:



Puedes hacer lo siguiente:

Código (php) [Seleccionar]
<?php

$link 
mysqli_connect('localhost','root','toor','test');
$result mysqli_query($link,'SELECT ID, nombre, categoria_de FROM brida');

/* declarar como array (strict) */
$menu = array();

while(
$row $result->fetch_array()){
   
// Si categoria_de es menor a 1 se considera como principal
   
if($row['categoria_de']<1){
      
// y se añade el nombre con index ID en el $menu.
      
$menu[$row['ID']] = array($row['nombre']);
   } else {
      
// Si categoria_de es mayor, se considera como subcategoria
      // asi que se añade al index de categoria_de.
      
$menu[$row['categoria_de']][]=$row['nombre'];
   }
}

/* Menu */
echo '<ul>';
// Por cada principal
foreach($menu as $principal){
   
// Imprimimos un li y su nombre.
   
echo '<li>'.$principal[0];
   echo 
'<ul>';
   
// Quitamos el nombre para que no se repita.
   
unset($principal[0]);
   
// Por cada subcategoria
   
foreach($principal as $sub){
      
// Imrpimimos nombre.
      
echo '<li>'.$sub.'</li>';
   }
   
// Cerrar principal.
   
echo '</ul></li>';
}
?>


Y el resultado sera:


  • Nuestros servicios
    • Arreglar Ordenadores
    • Reparar Moviles
  • Cotactar
    • Por email
    • Por correo

Saludos

:ohk<any>

Vaya, te has tomado la molestia de hacer el código.
Y es que a veces pienso que si no estuviera loco no podría salir adelante.
Lo que no se es capaz de dar, en realidad no se posee, uno es poseído por ello.

Brida

Muchas gracias drvy, este foro tendría que tener alguna forma de agradecer a la gente como tú.


ohk, hizo mal en poner el código? :'(

#!drvy

CitarVaya, te has tomado la molestia de hacer el código.

Es que no sabia como explicarlo con palabras xD

Citarohk, hizo mal en poner el código? :'(

En teoría, solo hay que ayudar en los problemas pero de tal modo que el usuario se haga su propio código. Así al menos aprenden algo xD.

Saludos

Brida

Pues muchas gracias, luego veré bien el código y a ver si me sale a la primera.


Mil gracias!

Brida

#6
Vale, me funciona perfectamente, pero por si alguien lo necesita (ya que el código es tuyo) pongo el código modificado, lo he modifico que habían unos pequeños fallos y es que no se cerraba los </ul>.
Además he cambiado los echo por variables para imprimir por si se realiza desde una función, como en mi caso que programo en POO.

Código (php-brief) [Seleccionar]

EDITADO


Muchas gracias a todos!!!




EDITO

Al final no me ha servido ya que me daba fallos, tenía problemas con el ul y los li, así que me he fijado en la idea y lo he hecho desde cero, os paso el código por si os sirve:

Código (php-brief) [Seleccionar]

$link = mysqli_connect('localhost','root','toor','test');
$result = mysqli_query($link,'SELECT ID, nombre, categoria_de FROM brida');

while($va = $re->fetch_array()){

if($va['padre']==0){
$menu[$va['ID']] = array($va['nombre']);
} else {
$menu[$va['padre']]["sub"][]=$va['nombre'];
}
}

/* Crea el Menú */
$menuvar.='<ul>';
foreach($menu as $principal => $valor){

// Si tiene sub...
if(empty($valor["sub"])){
// Si no tiene sub
$menuvar.='<li>'.$valor[0].'</li>';
}else{
// Si tiene sub
$menuvar.='<li class="sub">'.$valor[0].'<ul>';
foreach($valor["sub"] as $sub => $subvalor){
$menuvar.='<li>'.$subvalor.'</li>';
}
$menuvar.='</ul>';
}
}
$menuvar.='</ul>';

return $menuvar;


Como se ve lo que cambio principalmente es poner el array del tipo $va[ID]["sub"], para así comprobar más fácilmente si tiene subs o no.

De todos modos, muchísimas gracias por todo, no se me habría ocurrido tu idea, supongo que es como la gente lo hace :-P

Saludos!