2010-11-16 4 views
0

В интересах устранения столько вложенных запросов, как это возможно, я пытаюсь оптимизировать следующий запрос:Чтение последних значения в объединении без выполнения вложенных ВЫБЕРИТЕ

SELECT fp.id, 
      fp.user_id, 
      COUNT(c.id) AS num_replies, 
      c2.created AS latest_activity_time, c2.user_id AS latest_activity_user_id 
    FROM forum_posts fp 
LEFT JOIN comments c ON c.object_id = fp.id 
LEFT JOIN (SELECT created, user_id 
      FROM comments 
     ORDER BY created DESC 
      LIMIT 1) AS c2 ON fp.id = c2.object_id 
    WHERE fp.deleted != 1 
GROUP BY fp.id 

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

Так что, в основном, у нас есть таблица сообщений на форуме и таблица ответов на комментарии на эти должности. Каждый пост форума может иметь несколько ответов. Первое соединение используется для подсчета общего количества ответов, а второе соединение используется для получения самой последней информации ответа. То, что я вернусь из этого запроса что-то вроде этого:

sample nested query results

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

Спасибо!

Edit: Я немного поправил запрос, чтобы отразить тот факт, что мне нужно, чтобы вытащить обратно не только на latest_activity_time, но и в latest_activity_user_id. Извините за беспорядок!

ответ

3

Использование:

SELECT fp.id, 
      fp.user_id, 
      COUNT(a.id) AS num_replies, 
      c.date AS latest_activity_time, 
      c.user_id AS latest_activity_user_id 
    FROM FORUM_POSTS fp 
LEFT JOIN COMMENTS a ON a.object_id = fp.id   
LEFT JOIN (SELECT x.object_id, 
        x.date, 
        x.user_id 
      FROM COMMENTS x 
      JOIN (SELECT t.object_id, 
          MAX(t.date) AS max_date 
        FROM COMMENTS t 
       GROUP BY t.object_id) y ON y.object_id = x.object_id 
             AND y.max_date = x.date) b ON b.object_id = fp.id 
    WHERE fp.deleted != 1 
GROUP BY fp.id 
+0

Спасибо за ответ, @OMG Ponies. Теперь я понимаю, что, пытаясь уничтожить запрос, я достал самый важный бит: мне нужно захватить не только 'latest_activity_time', но также user_id и имя пользователя для этой последней активности. Есть ли способ сделать это, используя MAX (c.date) в выборе поля? – treeface

+0

@OMG Ponies: Извините за задержку. Я скорректировал свой первоначальный вопрос (надеюсь) более точную версию исходного запроса. Чтобы ответить на ваш вопрос напрямую: да, таблица 'comments' имеет свой собственный столбец' user_id'. – treeface

+0

@treeface: См. Обновление –

0

Как вы используете MySQL, вы должны быть в состоянии уйти со следующим:

SELECT fp.id, 
      fp.user_id, 
      COUNT(c.id) AS num_replies, 
      c.created AS latest_activity_time, 
      c.user_id AS latest_activity_user_id 
    FROM forum_posts fp 
LEFT JOIN comments c ON c.object_id = fp.id 
    WHERE fp.deleted != 1 
GROUP BY fp.id 
ORDER BY fp.id, c.created 
+0

Спасибо за ответ, но это не создает ожидаемого результата. Таблица комментариев по-прежнему сортируется по столбцу ID по умолчанию. – treeface