2

我使用 PHP 和 MySQL 创建了一个自定义论坛。我有两张表,一张用于线程,一张用于线程中的消息。

我正在实施一项功能,管理员可以选择一条消息作为最佳答案。在消息表中,best_answer 有一个 BOOL 列。

在列出线程的页面上,我想指出线程是否选择了最佳答案。

是否可以编写一个查询来选择所有线程,但也可以查看线程的消息,看看是否选择了最佳答案?

我正在尝试类似的东西:

SELECT *
FROM `threads`
JOIN `messages` ON `threads`.`id` = `messages`.`thread_id`
WHERE `messages`.`best_answer` = 1

但是,这只会拉出具有最佳答案的线程,我仍然需要它来拉动所有线程并拥有一列,以便我可以检查它是否有最佳答案。

只在线程表中添加一列以标记它是否选择了最佳答案会更好吗?

4

4 回答 4

4

有时,通过在子句中使用子查询更容易“看到”结果select

select t.*,
       (select MAX(bestanswer) from messages m where m.thread_id = t.id
       ) as HasBestAnswer
from threads t

不过,这会将结果限制为线程,这似乎是您想要的。

于 2013-02-20T18:32:55.323 回答
4

如果您正在寻找纯 SQL 解决方案,那么这应该适合您。

select * 
from threads
join (
    select threads.id, 
    sum(messages.best_answer) as has_best_answer
    from threads join messages
    on threads.id = messages.thread_id
    group by threads.id
)temp
on threads.id = temp.id

编辑:将查询缩短为

select * 
from threads
join (
    select thread_id, 
    sum(messages.best_answer) as has_best_answer
    from messages
    group by thread_id
)temp
on threads.id = temp.thread_id
于 2013-02-20T18:28:01.847 回答
1
SELECT *
FROM `threads`
LEFT JOIN `messages` ON `threads`.`id` = `messages`.`thread_id` AND `messages`.`best_answer` = 1
GROUP BY `threads`.`id`

如果可能,这将为您提供所有线程和最佳答案。 LEFT JOIN还用于显示未找到最佳答案的线程 您可以使用ON子句中的每个表达式来评估为真或假。

GROUP BY用于仅在结果集中为您提供一个具有特定thread_id且因此只有一个最佳答案的条目。

但是,您应该将“最佳答案”部分从messages表格中移出到threads表格中。因为一个线程只能有一个最佳答案,反之则不行。

于 2013-02-20T18:27:30.327 回答
0

This should pull the data as you are trying to:

SELECT threads.*, messages.best_answer
FROM threads
LEFT JOIN messages ON threads.id = messages.thread_id
GROUP BY threads.id
ORDER BY messages.best_answer DESC

And later, with the result set...

while ( $row = [...] ){
    if ( $row['best_answer'] > 0 ) { 
        // Best Answer is set, do something
    } else {
        // No best answer, do something else
    }
}

We do not include the WHERE clause, which was limiting your results to just those threads with a message whose best_answer column is set to 1. Now, we get all threads, and we can check in the loop whether a best_answer is 1 or 0.

于 2013-02-20T18:22:01.923 回答