使用聚合连接三个表

时间:2014-12-22 10:31:30

标签: sql postgresql left-join correlated-subquery

我有以下items表:

items:
id    pr1  pr2  pr3
-------------------
1     11   22   tt
...

和两个与项目相关联的表格:

comments:
item_id  text
-------------
1       "cool"
1       "very good"
...

tags:
item_id  tag
-------------
1        "life"
1        "drug"
...

现在,我希望获得一个包含条件item_id, pr1, pr2, count(comments), count(tags)的{​​{1}}列的表格。获得它的最佳方法是什么?我可以通过创建其他表来实现这一点,但我想知道是否有一种方法只使用一个SQL语句来实现这一点。我正在使用Postgres 9.3。

4 个答案:

答案 0 :(得分:2)

你可以加入,但是你需要小心,不要重复计算。例如。你可以使用子查询来获得你想要的东西。

SELECT i.id,i.pr1,i.pr2, commentcount,tagcount FROM
 items i
INNER JOIN
    (SELECT item_id,count(*) as commentcount from comments GROUP BY item_id) c
ON i.id = c.item_id
INNER JOIN
    (SELECT item_id,count(*) as tagcount from tags GROUP BY item_id) t
ON i.id = t.item_id

[编辑]根据评论,这里是左连接版本......

SELECT i.id,i.pr1,i.pr2, coalesce(commentcount,0) as commentcount,
      coalesce(tagcount,0) as tagcount FROM
     items i
    LEFT JOIN
        (SELECT item_id,count(*) as commentcount from comments GROUP BY item_id) c
    ON i.id = c.item_id
    LEFT JOIN
        (SELECT item_id,count(*) as tagcount from tags GROUP BY item_id) t
    ON i.id = t.item_id

答案 1 :(得分:2)

最简单的方法当然是获取select子句中的计数:

select 
  id, 
  pr1, 
  pr2,
  (select count(*) from comments where item_id = items.id) as comment_count,
  (select count(*) from tags where item_id = items.id) as tag_count
from items;

答案 2 :(得分:1)

试试这个:

SELECT i.id, i.pr1, i.pr2, A.commentCount, B.tagCount 
FROM items i
LEFT OUTER JOIN (SELECT item_id, COUNT(1) AS commentCount 
                 FROM comments 
                 GROUP BY item_id
                ) AS A ON i.id = A.item_id
LEFT OUTER JOIN (SELECT item_id, count(1) as tagCount 
                 FROM tags 
                 GROUP BY item_id
                ) AS B ON i.id = B.item_id;

答案 3 :(得分:-1)

select

  i.id
, i.pr1
, i.pr2
, count(c.item_id) as count_comments
, count(t.item_id) as count_tags

from items i
left outer join comments c on i.id = c.item_id
left outer join tags t on i.id = t.item_id
group by i.id, i.pr1, i.pr2

我使用LEFT OUTER JOIN也返回零点数。