嵌套SQL,查找哪些论坛有特定类型的帖子

时间:2013-01-08 15:07:39

标签: mysql sql nested-queries

我有一个我正在尝试运行的SQL语句,但它引发了一个错误:

SELECT fp.forum_id, COUNT(fp.forum_id) AS num_posts
FROM forums_posts fp
GROUP BY fp.forum_id
WHERE (
    SELECT COUNT(p.post_id) AS num_joined_posts
    FROM posts p
    WHERE p.post_type IN ('TypeA', 'TypeB', 'TypeC')
        AND p.forum_id = fp.forum_id
) > 0
ORDER BY num_posts DESC

forums_posts表是一个匹配论坛ID的关系表,用于发布ID,posts表(也存储帖子的论坛ID)只包含每个帖子的信息。我试图找出:哪些论坛有TypeA,TypeB或TypeC类型的帖子;以及每个论坛中有多少帖子。

嵌套的SQL语句从来都不是我的强项。有人能指出正确的方法吗?感谢。

3 个答案:

答案 0 :(得分:4)

where应该在group by之前。

您也可以使用明确的join

来编写此内容
SELECT fp.forum_id, COUNT(fp.forum_id) AS num_posts
FROM forums_posts fp join
     (SELECT p.forum_id, COUNT(p.post_id) AS num_joined_posts
      FROM posts p
      WHERE p.post_type IN ('TypeA', 'TypeB', 'TypeC')
      group by p.forum_id
     ) p
     on p.forum_id = fp.forum_id
GROUP BY fp.forum_id
ORDER BY num_posts DESC

虽然,我认为最有效的再现可能是:

SELECT fp.forum_id, COUNT(fp.forum_id) AS num_posts
FROM forums_posts fp join
GROUP BY fp.forum_id
having exists (select 1
               FROM posts p
               WHERE p.post_type IN ('TypeA', 'TypeB', 'TypeC') and
                     p.forum_id = pf.forum_id
               limit 1
              )
ORDER BY num_posts DESC

特别是如果您有帖子索引(forum_id,post_type)。我将条件从having子句移到where子句,因为在分组之后,这个比较可能会有更少的数据。

答案 1 :(得分:1)

试试这个 -

SELECT fp.forum_id, COUNT(fp.forum_id) AS num_posts
FROM forums_posts fp
WHERE (
    SELECT COUNT(p.post_id) AS num_joined_posts
    FROM posts p
    WHERE p.post_type IN ('TypeA', 'TypeB', 'TypeC')
        AND p.forum_id = fp.forum_id
) > 0
GROUP BY fp.forum_id
ORDER BY num_posts DESC

答案 2 :(得分:0)

我就是这样做的,使用连接SQL会更快。

SELECT * FROM 
(
  SELECT fp.forum_id,
       SUM(CASE p.post_type = 'TypeA' THEN 1 ELSE 0 END) AS A_Count,
       SUM(CASE p.post_type = 'TypeB' THEN 1 ELSE 0 END) AS B_Count,
       SUM(CASE p.post_type = 'TypeC' THEN 1 ELSE 0 END) AS C_Count
  FROM forums_posts fp
  LEFT JOIN posts p ON fp.forum_id = p.forum_id
  GROUP BY fp.forum_id
) T
WHERE T.A_count > 0 AND T.B_count > 0 AND T.C_count > 0 

我没有对此进行测试,因此可能存在拼写错误。