21:53 

Реализация комментариев как?

Plexx
Задача построить дерево комментариев.

Имеем таблицу
com_id
post_id
text

кол-во выводимых коментариев пусть будет 7

нужно выстроить их в таком виде.

-------------------
post_id =9
--------------------
com_id =75
com_id =71
--------------------
post_id = 10
--------------------
com_id =74
com_id =73
com_id =72
-------------------
post_id = 5
------------------
com_id =70
com_id =69

т.е. нужно комментарии не просто вывести, а объединить их к общей новости и если например новый комментарий под com_id =76 будет написан например в новости post_id = 5 то следовательно комментарии примут вид

-------------------
post_id = 5
------------------
com_id =76
com_id =70
-------------------
post_id =9
--------------------
com_id =75
com_id =71
--------------------
post_id = 10
--------------------
com_id =74
com_id =73
com_id =72

Помогите решить задачу.

@темы: PHP, Вопросы

Комментарии
2010-12-19 в 22:10 

Все люди делятся на две части.
SELECT * FROM comments WHERE `post_id` = '10' SORT BY `com_id` DESC LIMIT 7

2010-12-19 в 23:13 

Plexx
SELECT * FROM comments WHERE `post_id` = '10' SORT BY `com_id` DESC LIMIT 7

Ваш запрос выведет 7 комментариев которые написаны в post_id = 10
Ну и еще не SORT BY а ORDER BY наверное.

И данную задачу он ну никак не решает=)

2010-12-20 в 00:06 

 
кол-во выводимых коментариев пусть будет 7
Этот критерий неоднозначен. Научитесь полностью формулировать задачу.
Вы хотите вывести 7 последних комментариев в системе, сгруппировав их по принадлежности к одной записи (post) так, чтобы сами группы были отсортированы по времени последнего комментария (по убыванию), а комментарии в группе – также по убыванию времени добавления?

2010-12-20 в 00:12 

Plexx
я показал пример и нарисовал как должно выглядеть.

Вы хотите вывести 7 последних комментариев в системе, сгруппировав их по принадлежности к одной записи (post) так, чтобы сами группы были отсортированы по времени последнего комментария (по убыванию), а комментарии в группе – также по убыванию времени добавления?

Но вы правильно поняли.

2010-12-20 в 00:30 

 
Не стоит заставлять читателей читать мысли, они могут понять неправильно :)
Мало ли, вдруг закономерность в примере – совпадение, а автор имел в виду что-то другое? Нужно явным образом описать, что хочется получить в итоге.

Я думаю, в этом случае можно не выпендриваться.
При извлечении из БД комментариев по убыванию com_id, все post_id в этой выборке, встречающиеся впервые, тоже отсортированы по (последнему в группе) комментарию. Поэтому просто –

<?php

    $query 
mysql_query("SELECT post_id, com_id, text FROM comments ORDER BY com_id DESC LIMIT 7");
   
$posts = array();
    while (
$row mysql_fetch_assoc($query))
       
$posts[$row['post_id']][] = $row;
   
    foreach (
$posts as $post_id => $row)
    {
        echo 
"post_id = {$post_id}\n";
        foreach (
$row as $comment)
            echo 
"\tcom_id = {$comment['com_id']}\n";
    }
   
?>

2010-12-20 в 01:14 

Plexx
Что-то непонятное получается по вашему методу.. Дубли какие-то

Вывожу 5 комментариев

Выводит

post_id = 584 : com_id = 854,
post_id = 584 : com_id = 854,
post_id = 577 : com_id = 853,
post_id = 584 : com_id = 854,
post_id = 577 : com_id = 853, com_id = 851,
post_id = 584 : com_id = 854,
post_id = 577 : com_id = 853, com_id = 851, com_id = 850,
post_id = 584 : com_id = 854,
post_id = 577 : com_id = 853, com_id = 851, com_id = 850,
post_id = 578 : com_id = 849,

И еще вопрос по поводу массивов.

как мне в эту строчку echo "post_id = {$post_id}\n"; Передать не только id поста а еще и другие параметры поста (название, кол-во комментарие)

2010-12-20 в 01:17 

lugavchik
Я не бог, я так низко не опускаюсь.
А ещё можно вложенным селектом
SELECT * FROM (SELECT post_id, com_id, text FROM comments ORDER BY com_id DESC LIMIT 7) AS t ORDER BY post_id, com_id DESC

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

2010-12-20 в 01:34 

Plexx
lugavchik при таком запросе сортировка групп постов по времени последнего комментария не работает. а выводит посты по убыванию по id. А нужно что бы группы постов сортировались по последнему комментарию

2010-12-20 в 01:42 

 
Plexx, вы что-то напутали со вложенностью циклов. Проверьте код еще раз.

как мне в эту строчку echo "post_id = {$post_id}\n"; Передать не только id поста а еще и другие параметры поста (название, кол-во комментарие)
Я предлагаю вытащить информацию отдельным запросом. ID нужных постов уже есть. В примитивном случае хотя бы так –
<?php

    $query 
mysql_query("SELECT post_id, com_id, text FROM comments ORDER BY com_id DESC LIMIT 7");
   
$posts = array();
    while (
$row mysql_fetch_assoc($query))
       
$posts[$row['post_id']][] = $row;
       
   
$posts_info = array();
    if (
sizeof($posts))
    {
       
$query mysql_query("SELECT post_id, text FROM posts WHERE post_id IN (" join(", "array_keys($posts)) . ")");
        while (
$row mysql_fetch_assoc($query))
           
$posts_info[$row['post_id']] = $row;
    }
   
    foreach (
$posts as $post_id => $row)
    {
        echo 
"\npost_id = {$post_id}\n";
        echo 
"post text = " $posts_info[$post_id]['text'] . "\n";
       
// etc
       
foreach ($row as $comment)
            echo 
"\tcom_id = {$comment['com_id']}\n";
    }
   
?>



lugavchik, это бы работало, если бы там была колонка с датой последнего комментария к посту :)

2010-12-20 в 01:53 

Plexx
La personne mystique
заработало незнаю почему просто скопировал отсюда. первый вариант.

2-ой
очень сложная конструкция получается + 2 запроса

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

2010-12-20 в 02:06 

 
Plexx. хе-хе, это вы еще сложных конструкций не видели. :)
Сложность алгоритма как такового увеличивается не так уж сильно.
Если очень хочется, можно в первом запросе к каждой строке LEFT JOIN'ом прицепить нужные значения из второй таблицы (по post_id). Что, впрочем, будет плохой идеей, т.к. потери ресурсов на хранение и передачу избыточной информации явно превышают издержки на выполнение одного запроса. Правда, при 5-7 комментариях это вряд ли кто-нибудь заметит :)

2010-12-20 в 02:12 

Plexx
La personne mystique
Да я понимаю. Мне нужна информация что-бы знать какими методами лучше делать ту или иную задачу.

Left join применил но как в foreach его вывести? Ведь в $posts[$row['post_id']][] мы только id передаем.

$posts[$row['post_id']][] = $row;

foreach ($posts as $post_id => $row)
{
echo "post_id = {$post_id}\n";
foreach ($row as $comment)
echo "\tcom_id = {$comment['com_id']}\n";
}

2010-12-20 в 11:25 

lugavchik
Я не бог, я так низко не опускаюсь.
La personne mystique Да, что-то ступил, но для таких целей можно и ввести поле с датой, если технически возможно вносить изменения в модуль добавления комментариев и саму структуру БД. Расходы мелкие, а быстродействие повысят.

2010-12-20 в 11:39 

Plexx
мне тут вариант еще предложили... Не пробовал.. Скажите будет ли работать?

select t2.comm_id, t2.comm_text from comm t2 join (select max(comm_time) as max_post_time, post_id from comm t3 group by post_id) t1 using (post_id) order by max_post_time desc, t2.comm_time desc

что за using в запросе и для чего он?

2010-12-20 в 14:48 

Plexx
Сделал доп поле в постах date_comm timeshtamp и использовал запрос

SELECT * FROM comments as c, post as p WHERE p.id=c.post_id ORDER BY p.date_comm DESC, c.id DESC LIMIT 10

ну и сделал переменную как подсказал lugavchik «а при проходе записей проверять изменился но post_id и в случае смены выводить его данные и обновлять переменную.»

2010-12-26 в 00:54 

--==SS==--
Sanctus Satanas
По поводу using:

The USING(column_list) clause names a list of columns that must exist in both tables. If tables a and b both contain columns c1, c2, and c3, the following join compares corresponding columns from the two tables:
a LEFT JOIN b USING (c1,c2,c3)


Короче, в данном случае это то же самое, что «on t1.post_id = t1.post_id».

     

Сообщество PHP программистов

главная