结合三个SQL查询

时间:2010-11-18 20:03:00

标签: sql forum

我正在尝试为论坛的索引获取数据。获取所有板的列表,该板中的线程数以及该板中每个线程的帖子数。

SELECT 
board.*, 
IFNULL(a.thread_count, 0) AS thread_count,
b.post_count

FROM 
(SELECT * FROM r_forum_boards ORDER BY position) board 

LEFT OUTER JOIN 
    (SELECT r_forum_threads.board, r_forum_threads.id, 
         COUNT(r_forum_threads.id) AS thread_count 
     FROM r_forum_threads) a 
ON board.id = a.board

LEFT OUTER JOIN
(SELECT r_forum_posts.thread_id, COUNT(*) AS post_count 
 FROM r_forum_posts) b
ON b.thread_id = a.id

问题是post_count正在返回NULL。我已经尝试了一些不同的变体,但它们都没有起作用。

4 个答案:

答案 0 :(得分:1)

我从IFNULL猜测你的SQL是MySQL风格的。在这种情况下,您可以使用COUNT DISTINCT来简化操作。

SELECT 
board.id,
COUNT(DISTINCT r_forum_threads.id) AS thread_count,
COUNT(r_forum_posts.id) AS post_count
FROM board 
LEFT OUTER JOIN r_forum_threads ON board.id = r_forum_threads.board
LEFT OUTER JOIN r_forum_posts ON r_forum_posts.thread_id = r_forum_threads.id
GROUP BY board.id
ORDER BY board.position

根据您实际需要的board.*的数量,将列添加到SELECT和GROUP或将其用作子查询以加入board

答案 1 :(得分:0)

尝试加入GROUP子句:

LEFT OUTER JOIN 
(SELECT r_forum_threads.board, r_forum_threads.id, COUNT(r_forum_threads.id) AS thread_count FROM r_forum_threads GROUP BY r_forum_threads.id) a 
ON board.id = a.board

LEFT OUTER JOIN
(SELECT r_forum_posts.thread_id, COUNT(*) AS post_count FROM r_forum_posts GROUP BY r_forum_posts.thread_id) b ON b.thread_id = a.id

看看是否有诀窍。

答案 2 :(得分:0)

也许是因为您在子查询中缺少Group By子句?此外,您不需要第一个子查询。

Select board...
    , Coalesce(a.thread_count, 0) AS thread_count
    , b.post_count
From r_forum_boards 
    Left Join   (   
                Select r_forum_threads.board
                    , r_forum_threads.id
                    , Count(r_forum_threads.id) AS thread_count 
                From r_forum_threads
                Group By r_forum_threads.board
                    , r_forum_threads.id
                ) a 
        On a.board = board.id

    Left Join   (
                Select r_forum_posts.thread_id
                    , Count(*) AS post_count 
                From r_forum_posts
                Group By r_forum_posts.thread_id
                ) As b
        On b.thread_id = a.id
Order By r_forum_boards.position

您可以考虑稍微更改查询以便更容易测试:

Select board...
    , Coalesce(a.thread_count, 0) AS thread_count
    , A.post_count
From r_forum_boards 
    Left Join   (   
                Select r_forum_threads.board
                    , r_forum_threads.id
                    , Count(r_forum_threads.id) AS thread_count 
                    , Posts.post_count
                From r_forum_threads
                    Left Join (
                                Select r_forum_posts.thread_id
                                    , Count(*) AS post_count 
                                From r_forum_posts
                                Group By r_forum_posts.thread_id
                                )  As Posts
                        On Posts.thread_id = r_forum_threads.Id
                Group By r_forum_threads.board
                    , r_forum_threads.id
                ) As A
    On A.board = board.id
    Order By r_forum_boards.position

通过这种方式,您可以运行单个内部查询并确保A.获取结果,并获取post_count的值。

答案 3 :(得分:0)

我看到的问题是你试图获得2个相关但有些相互矛盾的数据,而且可能有2个查询可以为你提供所需的信息。

首先需要一个查询来获取每个电路板中的电路板名称和线程数。

  Select Board.*, GroupThread.threadCount
  FROM r_forum_boards Board 
  INNER JOIN (Select board_id, count(*) as threadCount from r_forum_threads group by board_id) GroupThread ON Board.board_id = GroupThread.board_id

其次,对于每个帖子,你需要帖子,这些帖子的计算方式基本相同:

  Select Thread.*, GroupPosts.postCount
  FROM r_forum_threads Thread 
  INNER JOIN (Select thread_id, count(*) as postCount from r_forum_posts group by thread_id) GroupPosts ON Thread.board_id = GroupPosts.thread_id

在每种情况下,您都会查看父对象,并对子项进行计数。