我有一个用户表(用户)和3个教程表(文本,视频和其他)。
每个教程都有rating_positive
和rating_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
答案 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