如何对来自不同表的总结列进行分组?

时间:2010-07-05 21:34:41

标签: mysql join sum

我有一个用户表(用户)和3个教程表(文本,视频和其他)。

每个教程都有rating_positiverating_negative列 并链接到用户(id)。

我想选择教程和总和最多的10个用户 他们的教程的正/负评级。

我尝试了以下查询,但它不起作用。它为tutorials_count / pos / neg返回太多结果。我怎么能正确地做到这一点?

SELECT  
    u.id AS user_id,  
    (COUNT(t.id) + COUNT(v.id) + COUNT(o.id)) AS tutorials_count,
    (SUM(t.rating_positive) + SUM(v.rating_positive) + SUM(o.rating_positive)) AS pos,
    (SUM(t.rating_negative) + SUM(v.rating_negative) + SUM(o.rating_negative)) AS neg
FROM
    user u LEFT JOIN trick t ON u.id = t.submitter_id
    LEFT JOIN video v ON u.id = v.submitter_id
    LEFT JOIN other o ON u.id = o.submitter_id
GROUP BY u.id
ORDER BY tutorials_count DESC
LIMIT 10

2 个答案:

答案 0 :(得分:2)

尝试使用您感兴趣的三个表中的UNION ALL创建子查询,然后加入:

SELECT  
    u.id AS user_id,  
    COUNT(submitter_id) AS tutorials_count,
    IFNULL(SUM(rating_positive), 0) AS pos,
    IFNULL(SUM(rating_negative), 0) AS neg
FROM user u
LEFT JOIN (
    SELECT submitter_id, rating_positive, rating_negative FROM trick
    UNION ALL
    SELECT submitter_id, rating_positive, rating_negative FROM video
    UNION ALL
    SELECT submitter_id, rating_positive, rating_negative FROM other
) T1
ON u.id = T1.submitter_id
GROUP BY u.id
ORDER BY tutorials_count DESC
LIMIT 10

答案 1 :(得分:1)

LEFT JOIN很好,并且在执行聚合之前执行比联合所有三个表更好。

问题是LEFT JOIN上的SUMmation意味着结果可能为NULL,您无法将其与其他列的总和一起添加。 IE:

... SUM(t.rating_positive) + 1
如果SUM(t.rating_positive)没有支持记录,

...将返回NULL,因为NULL + 1等于NULL。

你需要使用COALESCE将这些转换为零以使数学工作 - IFNULL是一个可接受的选择,但它是MySQL特定的,所以不太可能是可移植的:

   SELECT u.id AS user_id,  
          COALESCE(COUNT(t.id), 0) + COALESCE(COUNT(v.id), 0) + COALESCE(COUNT(o.id), 0) AS tutorials_count,
          COALESCE(SUM(t.rating_positive), 0) + COALESCE(SUM(v.rating_positive), 0) + COALESCE(SUM(o.rating_positive), 0) AS pos,
          COALESCE(SUM(t.rating_negative), 0) + COALESCE(SUM(v.rating_negative), 0) + COALESCE(SUM(o.rating_negative), 0) AS neg
     FROM USER u 
LEFT JOIN trick t ON u.id = t.submitter_id
LEFT JOIN video v ON u.id = v.submitter_id
LEFT JOIN other o ON u.id = o.submitter_id
 GROUP BY u.id
 ORDER BY tutorials_count DESC
    LIMIT 10