Questo dovrebbe fare il trucco:
$result = mysql_query("SELECT * FROM News");
$topicname = '';
// open list of topics
echo '<ul>';
// loop through topics
while($row = mysql_fetch_array($result)) {
if (!$row['TopicID']) {
// fake topic name for unsorted stuff
$row['TopicName'] = 'Sort Me';
}
if ($topicname != $row['TopicName']) {
if($topicname != ''){
// had a topic name, means we opened a list
// that hasn't been closed, close it.
echo '</ul>';
}
// print this topic and open the list of articles
echo '<li>' . $row['TopicName'] . '</li><ul>';
// update the current topic to be this TopicName
$topicname = $row['TopicName'];
}
// the news item
echo '<li>' . $row['NewsID'] . '"</li>';
}
if($topicname != ''){
// we saw at least one TopicName, we need to close
// the last open list.
echo '</ul>';
}
// end topic list
echo '</ul>';
Penso che il tuo vero problema sia che aprivi due elenchi ogni volta, ma ne chiudevi solo uno (anche spostando l'ultimo blocco all'interno dell'elenco).
Per la seconda parte della tua (nuova) domanda:
Avvertirò che per elenchi più grandi (diciamo, più di 300 elementi) il compromesso che sto facendo rispetto alla memorizzazione dell'elenco in memoria e all'iterazione due volte anziché semplicemente eseguire query per i conteggi necessari oscillerebbe nell'altro modo. Cioè, la soluzione seguente inserisce tutto in memoria, quindi esegue un'iterazione una seconda volta per stamparlo; un'alternativa sarebbe eseguire due query, una per trovare il numero di TopicNames univoci e l'altra per trovare il numero di elementi totali nell'elenco.
Inoltre, per la visualizzazione, vuoi davvero risolvere alcune ottimizzazioni per il layout, lo farò ingenuamente e creerò solo un numero (all'incirca) uguale di argomenti per colonna e quando la divisione non funziona, questo peserà verso sinistra. Vedrai dove puoi modificare o sostituire del codice per ottenere risultati diversi (e migliori?).
$columns = // user specified;
$result = mysql_query("SELECT * FROM News");
$num_articles = 0;
// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
if (!$row['TopicID']) {
$row['TopicName'] = 'Sort Me';
}
$dataset[$row['TopicName']][] = $row['NewsID'];
$num_articles++;
}
$num_topics = count($dataset);
// naive topics to column allocation
$topics_per_column = ceil($num_topics / $columns);
$i = 0; // keeps track of number of topics printed
$c = 1; // keeps track of columns printed
foreach($dataset as $topic => $items){
if($i % $topics_per_columnn == 0){
if($i > 0){
echo '</ul></div>';
}
echo '<div class="Columns' . $columns . 'Group' . $c . '"><ul>';
$c++;
}
echo '<li>' . $topic . '</li>';
// this lists the articles under this topic
echo '<ul>';
foreach($items as $article){
echo '<li>' . $article . '</li>';
}
echo '</ul>';
$i++;
}
if($i > 0){
// saw at least one topic, need to close the list.
echo '</ul></div>';
}