2013-03-17 3 views
0

У меня есть, например, следующие данные, возвращаемые из запроса, каждое имя пункт:Анализ одного столбца нескольких строк php

id  name  comment 
1  FF  hey 
1  FF  hey back! 
2  LL   
3  PP  i think its great! 
3  PP  me too 
3  PP  I'm not sure 
4  TT   
5  II  
6  KK  yesterday is the new tomorrow 

Когда я показываю это, каждый «элемент» имеет идентификатор и отображается в DIVs использовать LI.

Как вы можете видеть, хотя есть несколько комментариев иногда для «пункта», каждый на отдельной строке

То, что я хочу сделать, это отобразить каждый элемент, а затем показать комментарии по каждому пункту, если таковые имеются. Таким образом, я не могу группа ничем на этапе запроса, как секция комментариев является уникальным, но нужно сгруппировать на дисплей стадии

Так в настоящее время:

while ($row = mysql_fetch_array($result)){ 

echo '<li><div class=className><div class=itemName>'.$row[name].'</div>'; 

    if($row[comment]){ 

     echo '<div class=newRow>'.$row[comment].'</div>'; 

    } 

echo '</div></li>'; 

} 

Теперь, это не хорошо, потому что это создавать несколько дисплеев для одного и того же элемента с одним комментарием под каждым.

Могу ли я сделать это или я должен ввести данные по-разному?

Идеальный результат, например.

FF    LL    PP      etc etc etc 
hey       i think its great! 
hey back!      me too 
           I'm not sure 
+0

как говорится в первой строке, каждое имя является предметом –

ответ

2

Вы можете использовать GROUP_CONCAT() на вашем MySQL Query, чтобы сгруппировать все комментарии вместе для каждого имени

SELECT id, name 
GROUP_CONCAT(comment) AS comment 
FROM table 
GROUP BY name; 

затем explode()$row[comment] в коде PHP

while ($row = mysql_fetch_array($result)){ 

echo '<li><div class=className><div class=itemName>'.$row['name'].'</div>'; 

    if($row['comment'] != ""){ 

     $comments = explode(",",$row['comment']); 
     foreach($comments as $comment){ 
       echo '<div class=newRow>'.$comment.'</div>'; 
     } 

    } 

echo '</div></li>'; 

} 

Редактировать
Благодаря @CBroe, я теперь знаю tha т GROUP_CONCAT()group_concat_max_len имеет значение по умолчанию 1024. Вы хотите увеличить это перед запуском GROUP_CONCAT() запроса -

SET [GLOBAL | SESSION] group_concat_max_len = 10240; // must be in multiples of 1024 
SELECT id, name 
GROUP_CONCAT(comment) AS comment 
FROM table 
GROUP BY name; 

вы также должны быть осведомлены о max_allowed_packet, как это предел можно установить var_group_concat_max_len в.

Примечание: mysql_query() не позволяет несколько запросов, так что вам нужно будет сделать 2 mysql_query(), и вы можете использовать SET SESSION ... так, что все запросы в текущей сессии есть что max_len. Было бы лучше изменить функции mysql_ (которые амортизируются) и изменить на mysqli_ или PDO, поскольку они предлагают несколько вариантов запроса. а также проверить - http://php.net/manual/en/mysqlinfo.api.choosing.php

+0

Хорошее решение для группировки на базе базы данных. –

+1

Kepp in mind: _ «Результат усекается до максимальной длины, которая задается системной переменной' group_concat_max_len', которая имеет значение по умолчанию 1024. «_ (Из документов MySQL). Поэтому, если комментарии предназначены для чего-то как и система комментариев, 1024 символа могут пострадать только от нескольких комментариев. И даже для более коротких комментариев, можно легко попасть в этот предел, если их много. – CBroe

+0

@ CBroe Черт! Спасибо, что указали это, это было отличное решение, пока вы не отметили, что –

0

Не путайте доступ к данным с выходом, и вам будет легче нападать на подобные проблемы.

//Fetch and Sort 
$data = array(); 
while ($row = mysql_fetch_array($result)){ 
    $item = $row['item']; 
    if(!isset($data[$item]) { 
    $data[$item] = array(): 
    } 
    $data[ = $data[$item][] = $row['comment']; 
} 

//Output 
foreach($data as $item => $comments) { 
    echo '<li><div class=className><div class=itemName>'.$item.'</div>'; 
    foreach($comments as $comment) { 
     echo '<div class=newRow>'.$comment.'</div>'; 
    } 
    echo '</div></li>'; 
} 
0

Если вы не получаете данные обратно отсортированные по идентификатору уже, добавить в конце запроса:

ORDER BY name 

, который будет извлекать тот же список упорядочивается по идентификатору. Затем в цикле while добавьте переменную, которая отслеживает имя последнего элемента, которое вы видели. Если он изменится, добавьте новый li, иначе добавьте комментарий в конец вашего текущего списка.

+2

Я думаю, вы имеете в виду сортировку по имени, затем по ID. В противном случае (7, FF, Некоторые комментарии) нарушит вашу систему. –

+0

@PhilipWhitehouse Я думал, что идентификатор привязан к имени. Исправлена – eliot

Смежные вопросы