MySQL подсчет таблицы внуков, возвращающих разные результаты - PullRequest
0 голосов
/ 25 января 2011

Я занимаюсь разработкой PHP-форума.Этот форум использует четыре таблицы базы данных: форум, тема, сообщение, пользователь.

На моей целевой странице у меня есть список всех форумов, а также столбцы для последней темы (достигнуты с помощью объединения и внутреннего объединения), всего(простой подзапрос подсчета) и общее количество сообщений.

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

Таким образом, основной запрос:

select f.id as forum_id,
f.name as forum_name,
f.description,
t.forum_id,
#this subquery counts total threads in each forum
(select count(t.forum_id)
    from thread t
    where t.forum_id = f.id
    ) as total_threads,
#this query counts total posts for each forum
(SELECT COUNT( p.id )
    FROM post p
    WHERE p.thread_id = t.id
    AND t.forum_id = f.id
    GROUP BY f.id) as total_posts,
t.id as thread_id,
t.name as thread_name,
t.forum_id as parent_forum,
t.user_id,
t.date_created,
u.id as user_id,
u.username
from forum f
#    this join finds all latest threads of each forum
join
    (select forum_id, max(date_created) as latest
    from thread
    group by forum_id) as d on d.forum_id = f.id
#and this inner join grabs the rest of the thread table for each latest thread
inner join thread as t
on d.forum_id = t.forum_id
and d.latest = t.date_created
join user as u on t.user_id = u.id

Итак, если вы сосредоточите свое внимание на подзапросе общего количества постов, вы заметите, что я считаю все посты, где их идентификатор потока = идентификатор каждого потока, который затем= идентификатор каждого форума. Если я использую этот запрос по отдельности (и включаю псевдонимы таблиц, используемые в других местах основного запроса), он работает отлично.

однако при использовании в контексте основного запроса и спсевдонимы таблиц, предоставляемые в других местах, он возвращает только счет для первого потока p / forum.

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

Почему существует расхождение в содержании запроса и почему учитывается только первый поток при использовании в качестве вычисляемого поля в основном запросе?

1 Ответ

0 голосов
/ 25 января 2011

Поскольку t.forum_id и f.id имеют отношение только за пределами подзапроса, ваш подзапрос эквивалентен следующему:

IF(t.forum_id = f.id, 
(SELECT COUNT(p.id) 
FROM post p
WHERE p.thread_id = t.id
GROUP BY 1)
, 0) AS total_posts

Возможно, вы хотите что-то вроде этого:

SELECT f.name AS forum_name, COUNT(p.id) AS total_posts
FROM forum AS f
JOIN thread AS t ON t.forum_id = f.id
JOIN post AS p ON p.thread_id = t.id
GROUP BY f.id

Этот запрос будет возвращать по одной строке на форум и должен правильно включать количество сообщений.

Обратите внимание, что если в форуме нет сообщений, этот форум не будет возвращен этим запросом - вы можете изменить этос помощью LEFT JOINs вместо JOIN, если вам нужно следить за этим.

...