0

我正在开发一个 PHP 论坛。本论坛使用四个数据库表:forum、thread、post、user。

在我的登录页面上,我列出了所有论坛,以及最新线程(通过连接和内部连接实现)、总线程(简单计数子查询)和总帖子的列。

我有一个大小适中的查询,它返回上述所有内容,并且一切都运行得很好——除了帖子总数。

因此,主要查询是:

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

因此,如果您将注意力集中在上面的总帖子子查询上,您会注意到 htat 我正在计算所有帖子,其中他们的线程 id = 每个线程的 id,然后 = 每个论坛的 id,如果我单独使用这个查询(并包括在主查询中其他地方使用的表别名)它完美地工作。

但是,当在主查询的上下文中使用时,并且在其他地方提供表别名时,它只返回第一个线程 p/forum 的计数。

如果我尝试在子查询中声明表别名,它会返回错误,即返回了不止一行。

为什么查询内容存在差异,为什么在主查询中用作计算字段时只计算第一个线程?

4

1 回答 1

0

由于 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 JOIN 而不是 JOIN 来更改它。

于 2011-01-25T16:54:40.820 回答