使用单个查询聚合两个不同的事件表

时间:2013-12-14 19:08:42

标签: sql postgresql join

我有一个简单的架构,其中包含posts的表格和两个跟踪viewsupvotes的表格:

CREATE TABLE posts (
    id integer NOT NULL PRIMARY KEY,
    title VARCHAR(255) NOT NULL
);

CREATE TABLE views (
    post_id integer,
    value integer
);

CREATE TABLE upvotes (
    post_id integer,
    value integer
);

请注意,viewsupvotes中的元组代表了一般数量的观看次数和赞成票。我想汇总帖子,显示总观看次数和支持率

我认为这很简单,但不幸的是我失败了。

这是我的疑问:

SELECT posts.title,
       SUM(views.value) AS views,
       SUM(upvotes.value) AS upvotes

FROM posts
    LEFT OUTER JOIN views ON (posts.id = views.post_id)
    LEFT OUTER JOIN upvotes ON (posts.id = upvotes.post_id)

GROUP BY posts.id;

我理解为什么会失败,但我真的不明白该怎么做。如果我需要运行两个不同的查询并在应用程序级别聚合结果,我很好。我只是想了解单个查询是否可行

我创建了sqlfiddle with my test case

PS:我设法只使用一个通用表来跟踪事件,但我想保持表分开。 sqlfiddle here

2 个答案:

答案 0 :(得分:4)

您可以安全地计算子查询中的值。这样可以避免您总结重复值,从而导致无效结果。

SELECT  p.id,
        p.title,
        COALESCE(v.totalView, 0) totalView,
        COALESCE(u.totalUpvote, 0) totalUpvote
FROM    posts p
        LEFT JOIN
        (
            SELECT  post_id,
                    SUM(v.value) totalView
            FROM    views v
            GROUP   BY post_id
        ) v ON p.id = v.post_ID
        LEFT JOIN
        (
            SELECT  post_id,
                    SUM(u.value) totalUpvote
            FROM    upvotes u
            GROUP   BY post_id
        ) u ON p.ID = u.post_ID

答案 1 :(得分:1)

SQL Fiddle

在两个单独的选择之间进行连接

SELECT * FROM(SELECT posts.title,
       SUM(views.value) AS views
FROM posts
    LEFT OUTER JOIN views ON (posts.id = views.post_id)
GROUP BY posts.id)as x
JOIN(
SELECT posts.title,      
       SUM(upvotes.value) AS upvotes
FROM posts
    LEFT OUTER JOIN upvotes ON (posts.id = upvotes.post_id)
GROUP BY posts.id)as y on x.title=y.title