2012-05-07 5 views
2

У меня есть таблица со следующими ключевыми полями: commentid, comment, time, parentidMySQL OrderBy запрос GroupBy,

Комментарии бывают двух типов, regular и replies. Регулярные имеют parentid 0; ответы имеют родительский знак, равный комментарию, на который они отвечают.

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

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

В качестве примера, я хотел бы следующий порядок:

time3 commentid3 parentid0 
time2 commentid2 parentid0 
    parentid2 commentid4 time4 (this one is a reply) 
    parentid2 commentid5 time5 (this one also reply) 
time1 comment1 parentid0 

Я попытался SELECT * from comments GROUP BY parentid ORDER BY TIME DESC, но это не сработало. При необходимости я могу добавить еще один столбец. Мы ценим любые предложения! Спасибо.

ответ

1

Я делаю несколько предположений здесь. Я предполагаю, что ваш commentid является автоматически увеличивающимся идентификатором, поэтому это означает, что порядок вставки будет от самого старого до самого нового. Это не будет работать, если вы не используете auto-incrementing ids или если у вас есть какие-то частичные функции сохранения с этими таблицами. Так что это немного хрупко.

Я также предполагаю, что parent_id имеет значение null, если он является родительским.

SELECT commentid, comment, time, parent_id, if(parent_id = 0, commentid, parent_id) thread 
FROM comments 
ORDER BY thread desc, time asc 

В любом случае, чтобы добавить дополнительную информацию.

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

EDIT:

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

+0

Как установить поток? Это то же самое, что и комментарий? если я это правильно понимаю, он выводит исходные потоки. Я пытаюсь подражать disqus, livefyre с комментариями во время спуска, но с ответами, отображаемыми с отступом ниже комментария, на который они отвечают. Отступы - это просто проблема форматирования, поэтому мне просто нужно, чтобы ответы были помещены под соответствующими родительскими комментариями. – user1260310

+0

Тема может быть не лучшим словом для нее, но она задается условным, если в предложении select. Поэтому, если parent_id имеет значение null, мы будем использовать commentid для идентификатора потока. Это просто для упорядочения и группировки всех комментариев вместе. – Gohn67

+0

Чтобы пояснить, нить не является реальным столбцом, это просто псевдоним для функции if. Мы обманываем здесь поток, потому что мы предполагаем, что потоки вводятся в порядке от старейшего до новейшего, и затем каждый из сгруппированных комментариев сортируется по столбцу времени. – Gohn67

1

Вы не можете получить результат с «древовидную» из SQL-запроса (ну есть способы, но они не кажутся практически использовать здесь)

Что вы можете сделать, это получить все из ДАННЫЕ регулярные и ответы (что подразумевает, что «регулярные» данные будут реплицированы, если у них много ответов, и вам придется обрабатывать их после получения данных, чтобы получить результат «дерева»).

результат будет выглядеть так:

regular.time, regular.commentid, replies.commentid, replies.time 

, если у регулятора нет комментариев, replies.comment id и ответы.время будет нулевой

Query (с «я оставил присоединиться к») будет выглядеть так, что (я переехал несколько полей, которые кажутся бесполезными сейчас)

select 
regular.time as regulartime, 
regular.commentid as regularid, 
replies.commentid as repliesid, 
replies.time as repliestime 
from comments regular 
left join comments replies on replies.parentid = parent.commentid 
where regular.parentid = 0 
order by regular.time desc, replies.time asc 

После Вашего примера, вы должны получить

time3 commentid3 null  null 
time2 commentid2 commentid4 time4 (this one is a reply) 
time2 commentid2 commentid5 time5 (this one also reply) 
time1 commentid1 null  nulll 
+0

Вы предлагаете две таблицы, регулярные и ответы? – user1260310

+0

нет, одна таблица, но псевдонимы в запросе –

+0

Мне нужно читать псевдонимы, так как я не сразу понимаю синтаксис. – user1260310

1

Чтобы получить оба слоя данных, вам понадобится UNION только самого верхнего слоя исходного комментария, а другой - для любых ВОЗМОЖНЫХ ответов. Первый столбец первой части запроса будет содержать 1 или 2 для сортировки. Это будет использоваться для размещения исходного сообщения в верхней части группы для заданного вопроса ... тогда все ответы будут отображаться в естественном порядке после этого.

Кроме того, чтобы сохранить правильную группировку по исходной дате/времени, я сохраняю исходное время комментариев комментария с помощью записей «2» CommentType, чтобы они оставались сгруппированными с одинаковой исходной базой времени, но хватайте фактический комментарий и время RESPONSE (псевдоним «r») для их соответствующей сортировки.

select 
     PreQuery.* 
    from 
     (select 
       '1' as CommentType, 
       c.Time as OriginalTime, 
       c.CommentID StartingCommentID, 
       c.Comment, 
       c.Time as LastTime, 
       c.CommentID as EndCommentID 
      from 
       comments c 
      where 
       c.ParentID = 0 
     UNION ALL 
     select 
       '2' as CommentType, 
       c.Time as OriginalTime, 
       c.CommentID StartingCommentID, 
       r.Comment, 
       r.Time as LastTime, 
       r.CommentID as EndCommentID 
      from 
       comments c 
       join comments r 
        on c.CommentID = r.ParentID 
      where 
       c.ParentID = 0) PreQuery 
    order by 
     PreQuery.OriginalTime DESC, 
     PreQuery.StartingCommentID, 
     PreQuery.CommentType, 
     PreQuery.LastTime 

Это должно дать вам результаты, которые я думаю, что вы ищете (слегка измененный)

CommentType OriginalTime StartingCommentID Comment LastTime EndCommentID 
1   Time3   ID3    Comm3 Time3  ID3 <-- ID 3 IS the start 
1   Time2   ID2    Comm2 Time2  ID2 <-- ID 2 is the start of next 
2   Time2   ID2    Comm4 Time4  ID4  <- ID4 is reply to orig ID2 
2   Time2   ID2    Comm5 Time5  ID5  <- another reply to ID2 
1   Time1   ID1    Comm1 Time1  ID1 <-- start of new comment ID1 

Таким образом, для всех строк, 2-го и 3-го столбцов всегда будет представлять родительский идентификатор, который начинает первый комментарий ... и для тех, у кого есть комментарий типа = 1, комментарий, последний и конечный идентификатор комментария - это фактический контент из исходного комментария. Для типа комментариев = 2 окончательный комментарий, последний комментарий и последний комментарий будут идентификатором записи RESPONSE.

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