如何通过MySQL LEFT JOIN、COUNT与SUM实现指定邮件统计结果?
解决邮件发送统计的SQL查询问题
嘿,我来帮你搞定这个统计需求!你要计算指定日期范围内每个用户的成功发送和失败邮件数,核心是用CASE表达式配合SUM函数来实现条件计数,具体做法如下:
完整的SQL查询语句
SELECT Emails_Table.user_id, Users_Table.username, SUM(CASE WHEN Emails_Table.status = 'sent' THEN 1 ELSE 0 END) AS total_sent, SUM(CASE WHEN Emails_Table.status = 'fail' THEN 1 ELSE 0 END) AS total_failed FROM Emails_Table LEFT JOIN Users_Table ON Emails_Table.user_id = Users_Table.user_id WHERE Emails_Table.date BETWEEN '2017-05-29' AND '2018-01-22' GROUP BY Emails_Table.user_id, Users_Table.username ORDER BY Emails_Table.user_id;
关键部分解释
统计成功发送数(total_sent)
用CASE WHEN status = 'sent' THEN 1 ELSE 0 END对每一行进行判断:如果邮件状态是sent,就标记为1,否则标记为0。再用SUM()把这些标记值加起来,就得到该用户成功发送的邮件总数。统计失败数(total_failed)
逻辑和上面完全一致,只是判断条件改成status = 'fail',SUM后得到失败的邮件总数。GROUP BY的规范
因为我们SELECT里包含了user_id和username两个非聚合列,所以GROUP BY需要同时包含这两个字段(不同数据库的SQL模式可能有差异,但这样写兼容性最好,避免出现分组错误)。
额外说明
如果你的需求是包含所有用户(哪怕该用户在指定日期内没有任何邮件记录),可以把查询的主表换成Users_Table,再调整JOIN顺序和条件,同时处理NULL情况:
SELECT Users_Table.user_id, Users_Table.username, SUM(CASE WHEN Emails_Table.status = 'sent' THEN 1 ELSE 0 END) AS total_sent, SUM(CASE WHEN Emails_Table.status = 'fail' THEN 1 ELSE 0 END) AS total_failed FROM Users_Table LEFT JOIN Emails_Table ON Users_Table.user_id = Emails_Table.user_id AND Emails_Table.date BETWEEN '2017-05-29' AND '2018-01-22' GROUP BY Users_Table.user_id, Users_Table.username ORDER BY Users_Table.user_id;
这样用户john(user_id=5)会显示total_sent=0和total_failed=0。
内容的提问来源于stack exchange,提问作者James Arnold
相关产品推荐
相关产品推荐

