Agrupe los resultados de mysql por categoría y muéstrelos en grupos debajo de cada categoría

Intento crear un menú CSS simple que obtenga los datos de una tabla mysql.

Mi idea es tener un menú como este

Category 1 - link 1 - link 2 - link 3 Category 2 - link 1 - link 2 - ect... 

cada enlace tiene un campo llamado “categoría”. Por lo tanto, quiero agrupar y mostrar los enlaces en el menú por categoría.

Tengo una agrupación mysql como

 $sql = "SELECT * FROM content group by category"; $result = mysql_query($sql); 

y luego tengo el html como este

  

La tabla db se ve así

 CREATE TABLE IF NOT EXISTS `content` ( `id` int(11) NOT NULL AUTO_INCREMENT, `menu_name` text, `menu_name_en` text, `menu_url` varchar(255) NOT NULL DEFAULT '', `header_name` text, `header_name_en` enum('MEDIA','GENERAL') NOT NULL DEFAULT 'MEDIA', `text` longtext NOT NULL, `text_en` text, `category` enum('Category 1', 'Category 2') NOT NULL DEFAULT 'Category 1', `date` date NOT NULL DEFAULT '0000-00-00', `visible` char(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ); INSERT INTO content (id, menu_name, menu_name_en, menu_url, header_name, header_name_en, text, text_en, category, date, visible) VALUES (26, 'test name', '', 'test_url', 'test name', '', '

test text

', '

text text

', 'MEDIA', '2014-02-23', '1');

Por lo tanto, estoy teniendo problemas para poner los resultados en el bucle y crear el html por categoría.

Leí muchas publicaciones aquí con contenido similar pero no pude lograr el resultado que quería. Cualquier ayuda será muy apreciada. ¡Gracias!

Yo usaría la ORDER BY category lugar. Puede iterar el conjunto de resultados como

 $old = null; foreach ($st as $s) { if $old != $s['id'] echo 'Main category'; $old = $s['id']; echo 'subcategory' 

Actualizar

Hasta el momento, existen tres soluciones posibles en este hilo para el problema en sí.

Opción original 1

 SELECT * FROM content group by category foreach SELECT * FROM content WHERE category=$cat['category'] 

Si uno solo desea obtener cada categoría principal una vez, debe usar DISTINCT lugar. No se debe usar GROUP BY sin usar ninguna función de agregación. La combinación de GROUP BY con SELECT * está limitada a (principalmente) MySQL. No puede seleccionar columnas arbitrarias en este caso en ASNI SQL.

Una variante de la opción 1

 SELECT DISTINCT category FROM content ORDER BY category foreach SELECT * FROM content WHERE category=$cat['category'] 

Esta es la versión corregida con DISTINCT lugar de GROUP BY .

Todavía carece de llamadas de consulta anidadas. Para 5 categorías principales, esto genera 5 consultas en el ciclo. Para 10 categorías principales, ya hay 10 consultas dentro. Uno debe evitar este tipo de crecimiento en general.

Opción 3

 SELECT * FROM content ORDER BY category, menu_name 

utilizable con el código anterior.

Esto es preferible a las otras opciones que se muestran debido a diferentes razones:

  • Solo necesita una única consulta de base de datos para recostackr todos los datos a la vez. La base de datos gasta (en consultas sencillas) la mayor parte del tiempo en analizar la statement SQL que se proporciona y solo una fracción de tiempo para recostackr realmente los datos que solicitó. Si proporciona muchos códigos SQL, debe pasar mucho tiempo analizándolo. Si proporciona menos código, tiene menos que hacer.
  • Es más fácil para una base de datos obtener los datos una sola vez, ordenarlos una vez y devolvérselos una vez, en lugar de reunir una parte, ordenar una pieza, devolver una pieza y comenzar de nuevo.

sigue sin especificar la opción 4

Existe una solución adicional hasta ahora no declarada. Uno puede usar declaraciones preparadas, preparar el SQL una vez y ejecutarlo con diferentes ID. Esto todavía consultaría todas las categorías dentro del bucle, pero evitaría la necesidad de analizar el código SQL todo el tiempo.

En realidad, ahora no sé si esto es mejor o peor (o algo intermedio) que mi solución.

La instrucción SQL GROUP BY agrupa los resultados de modo que solo se devuelva una fila para cada categoría. Esto se usa generalmente junto con una función agregada como count (), para contar cuántos elementos hay en cada categoría. Lo que necesita es un ORDER BY como dijo GhostGambler, o una consulta separada para cada categoría como se muestra a continuación. Sin embargo, como parece que solo tiene 2 categorías, este enfoque parece innecesariamente complicado.

  $q=$db->query("SELECT DISTINCT category FROM content ORDER BY category"); foreach($q as $cat){ echo '
  • '; echo 'https://stackoverflow.com/questions/21967276/group-mysql-results-by-category-and-display-them-into-groups-under-each-category/'.$cat['category'].''; echo '
  • '; }

    Tu consulta es incorrecta

     $sql = "SELECT * FROM content WHERE group by category"; 

    debiera ser

     $sql = "SELECT * FROM content group by category"; 

    Además, dado que mysql está en desuso, evítelo. Use mysqli o PDO en su lugar

    Supongo que se está preguntando si desea agregar un submenú dinámicamente. Si es así, primero cree una segunda tabla para el submenú y añada una relación entre el menú y las tablas del submenú.

     $select=$connection->query("select * from menus"); while($result=$select->fetch_assoc()){ echo "
  • "; echo "".$result['MenuTitle'].""; $menuid=$result['MenuId']; if($result==true){ $selectsubmenu=$connection->query("Select * from submenu where menuid='$menuid'"); echo ""; } echo "
  • "; }