[英]SUM multiple columns from multiple tables with filtering
我们的用户可以在移动设备和Web上喜欢,保存,共享和创建内容。 这些动作中的每一个都由一个表来表示,该表的source
列中包含mobile
或web
值。
我需要找到最活跃的移动用户,用喜欢,分享,保存和创建的总数表示。
User has_many Likes, Likes belong_to User
User has_many Shares, Shares belong_to User
User has_many Saves, Saves belong_to User
User has_many Creates, Creates belong_to User
// User Table
id | full_name | email | ...
// Likes, Share, Save, Create Table
id | user_id | source | ...
我理想的输出将是这样的:
// ordered by grand total
id | full_name | total likes | total saves | total creates | total shares | grand total
我可以为这些操作之一创建查询:
SELECT u.full_name, u.id, COUNT(*) as "Likes"
FROM users u, likes l
WHERE u.id = l.user_id and l.source = 'mobile'
GROUP BY full_name
ORDER BY COUNT(*) DESC
但是我不确定如何总结他们在不同表中的所有动作。
我们的users
表具有likes_count
, saves_count
和create_count
字段,这些字段在执行每个操作时都会更新,但随着移动和网络活动的增加而增加,如上所述,我只需要移动设备。 它还缺少份额计数,我希望在试图弄清楚我们最活跃的移动用户是谁的情况下将其包括在内。
我不确定从哪里开始,因为这似乎是一个非常麻烦的查询。
我们正在使用Rails,所以我可以使用基于控制台的解决方案(它将转储SQL)。
尝试:
SELECT username, ident, SELECT SUM(COUNT(l.id)+count(sa.id)+...) as Total
FROM(
SELECT u.full_name as username, u.id as ident, COUNT(l.id) AS likes,
count(sa.id) as saves, ...
FROM users u, likes l, saves sa, ...
WHERE u.id = l.user_id and l.source = 'mobile'
AND (u.id = sa.user_id and sa.source = 'mobile')
...
GROUP BY full_name)
ORDER BY Total DESC
这就是我最后得到的。 创建多个虚拟表并将它们加入用户的全名:
SELECT likes_table.full_name,
COALESCE(likes_count,0) AS likes,
COALESCE(saves_count, 0) AS saves,
COALESCE(share_count,0) AS shares,
COALESCE(create_count,0) AS "create",
(COALESCE(likes_count,0) + COALESCE(saves_count,0) + COALESCE(share_count,0) + COALESCE(create_count,0)) AS TOTAL
FROM (
SELECT u.full_name, count(*) AS likes_count
FROM users u, likes l
WHERE u.id = l.user_id
AND l.source = 'mobile'
GROUP BY u.full_name) AS likes_table
LEFT JOIN (
SELECT u.full_name, COUNT(*) AS saves_count
FROM users u, saves s
WHERE u.id = s.user_id
WHERE s.source = 'mobile'
GROUP BY u.full_name) AS saves_table
ON likes_table.full_name = saves_table.full_name
LEFT JOIN (
SELECT u.full_name, COUNT(*) AS share_count
FROM users u, shares sh
WHERE u.id = sh.user_id
AND sh.source = 'mobile'
GROUP BY u.full_name) as shares_table
ON likes_table.full_name = shares_table.full_name
LEFT JOIN (
SELECT u.full_name, COUNT(*) AS create_count
FROM users u, create c
WHERE u.id = c.user_id
AND c.source = 'mobile'
GROUP BY u.full_name) as create_table
ON likes_table.full_name = create_table.full_name
ORDER BY TOTAL DESC
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.