Сортировка MySQL в группе с несколькими объединениями - PullRequest
4 голосов
/ 06 марта 2011

Я пытаюсь работать со следующими таблицами: ответы пользователей (id, name) (id, name, slug) на сообщения (id, title, content, topicid, authorid, datetime, slug) ответы (id, authorid, threadid), content, datetime)

Я хочу создать список сообщений, упорядоченных по последнему ответу (или дате публикации, если ответов нет).Каждый список должен содержать: заголовок сообщения, количество ответов, дату публикации, дату последнего ответа, имя автора, имя человека, который ответил в последний раз и т. Д.

Я могу получить все, кроме даты и автора последнего ответа.Дату можно сделать через MAX (replies.datetime), но я не знаю, как получить последнего автора.

Моя последняя попытка была использовать исключающее соединение:

select posts.id, posts.title, posts.authorid, posts.topicid, posts.content, posts.datetime, count(replies.id) as replies, r2.datetime, replies.datetime, GREATEST(posts.datetime, coalesce(max(replies.datetime), posts.datetime)) as latesttime, users.name as author, commenters.name as commenter, r2.id 
from posts 
left join replies on replies.threadid = posts.id 
left join users on users.id = posts.authorid 
left join users commenters on commenters.id = replies.authorid
left join replies as r2 on replies.id = r2.id and replies.datetime < r2.datetime 
where r2.id is null 
group by posts.id 
order by latesttime DESC, replies.datetime DESC 
limit 20;

К сожалению, это все еще не получит последний комментарий автора.Есть идеи?

Ответы [ 2 ]

2 голосов
/ 06 марта 2011

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

SELECT 
      p.id,
      p.title,
      p.content,
      p.topicid,
      p.authorid,
      p.datetime as postdate,
      p.slug,
      postUser.Name as PostAuthor,
      coalesce( MaxReplyUser.NumReplies, 0 ) NumReplies,
      coalesce( MaxReplyUser.name, '' ) ReplyUser,
      coalesce( MaxReplyUser.AuthorID, 0 ) ReplyAuthor,
      coalesce( MaxReplyUser.ThreadID, 0 ) ReplyThread,
      coalesce( MaxReplyUser.DateTime, '' ) ReplyDateTime,
      coalesce( MaxReplyUser.Content, '' ) ReplyContent
   from 
      Posts p
         left join 
            ( SELECT 
                     u1.name,
                     r1.authorid,
                     r1.threadid,
                     r1.datetime,
                     r1.content,
                     MaxReplies.NumReplies
                  from 
                    ( SELECT 
                            threadid,
                            COUNT(*) as NumReplies,
                            MAX( id ) as MaxReplyID
                         from 
                            replies
                         group by 
                            threadID ) MaxReplies
                       INNER JOIN replies r1
                          ON MaxReplies.MaxReplyID = r1.id
                          INNER JOIN Users u1
                             ON r1.AuthorID = u1.ID ) MaxReplyUser
           ON p.id = MaxReplyUser.threadID
         inner join users postUser
            ON p.authorid = postuser.id
    order by 
       if( MaxReplyUser.threadID IS NULL, p.DateTime, MaxReplyUser.DateTime ) DESC
1 голос
/ 06 марта 2011

Вы это тестируете?

SELECT posts.id, posts.title, posts.authorid, posts.topicid, posts.content, posts.datetime, 
(SELECT name FROM users WHERE id = posts.autorid) "Author",
(SELECT COUNT(*) FROM replies WHERE threadid = posts.id) "Replies",
(SELECT MAX(datetime) FROM replies r WHERE threadid = posts.id) "Lastreplytime",
(SELECT (SELECT name FROM users WHERE id = r.authorid LIMIT 1) FROM replies r WHERE threadid = posts.id ORDER BY datetime DESC LIMIT 1)
FROM posts 
ORDER BY Lastreplytime DESC
LIMIT 20;
...