MySQL JOIN 2 个表并分别获取两个表的总和

Posted

技术标签:

【中文标题】MySQL JOIN 2 个表并分别获取两个表的总和【英文标题】:MySQL JOIN 2 tables and get sum for both tables separately 【发布时间】:2019-07-22 02:52:03 【问题描述】:

我有 2 张桌子。我需要从两个表中获得收入 - 将具有相同日期和相同 user_id 的收入相加(输出在图表中 - 每个用户的仪表板)。

我创建了一个运行良好的 SQL 查询,但是从第二个表中我从所有用户那里获得了收入,我只需要分别显示每个用户的收入,并且表中是否存在带有日期的 user_id。我想提一下,每个用户在 2 个表中没有行,只有使用此服务的用户。见下文:

表:用户收入

USER_ID                CDATE             REVENUE
1                      2019-03-15        15
2                      2019-03-15        18
5                      2019-03-15        29
9                      2019-03-15        11

表:user_revenue_publisher

USER_ID                CDATE             REVENUE
1                      2019-03-15        15
1                      2019-03-15        50
9                      2019-03-15        21
9                      2019-03-15        18

我的 SQL 查询:

SELECT  a.user_id,
        a.cdate,
        a.revenue,
        SUM(b.revenue) as total_revenue
FROM    user_revenue a
           INNER JOIN user_revenue_publisher b
                ON a.cdate = b.cdate
WHERE   a.user_id=$id AND a.cdate >= DATE(NOW() - INTERVAL 30 DAY) group by cdate asc

($id = is ID user after login)

我需要将这些查询合并为一个:

$result = $pdo->query("select * from user_revenue where user_id=$id AND `cdate` >= DATE(NOW() - INTERVAL 30 DAY)"); 
$result2 = $pdo->query("select * from user_revenue_publisher where user_id=$id AND `cdate` >= DATE(NOW() - INTERVAL 30 DAY)"); 

我的 SQL 错误:

USER_ID                CDATE             REVENUE
1                      2019-03-15        80 (correct)
USER_ID                CDATE             REVENUE
2                      2019-03-15        104 (BAD value, I need sum = 18)

我需要结果:

USER_ID                CDATE             REVENUE
1                      2019-03-15        80
USER_ID                CDATE             REVENUE
2                      2019-03-15        18

对于新用户,例如新注册的 USER_ID = 24 应该是

USER_ID                CDATE             REVENUE
24                     2019-03-15        0

我很高兴能得到任何帮助。

【问题讨论】:

【参考方案1】:

有几个问题: GROUP BY 需要所有不是聚合函数的列(例如 SUM()。此外,您在查询中显示两个 REVENUE 列,但在您的示例中只显示一个,所以它是很难说是哪一个问题(尽管我认为是 sum())。

我认为这应该给你你想要的:

   SELECT  a.user_id,
        a.cdate,
        a.revenue,
        SUM(b.revenue) AS total_revenue
           FROM    user_revenue a
           INNER JOIN user_revenue_publisher b
                 ON a.cdate = b.cdate
        WHERE a.user_id= $id  group by a.User_ID,a.revenue, a.cdate

【讨论】:

谢谢,但是 SQL 仍然不能正常工作。当我以新用户身份登录时,我看到所有用户的总收入,为什么?在 php foreach 我有 foreach($result as $row) $final_revenue = $row['revenue'] + $row['total_revenue'];请问你可以创建一个新的sql吗?我认为我的 SQL 完全不好。 我只需要在过去 30 天的同一天和 user_id 的一张表和第二张表的总收入。带有过去 30 天收入的经典图表。【参考方案2】:

如果您想要没有收入的用户,那么您需要一个外部联接(或相关子查询)。所以,我建议:

select ur.user_id, ur.cdate, ur.revenue,
       ur.revenue + coalesce(sum(urp.revenue), 0) as total_revenue
from user_revenue ur left join
     user_revenue_publisher urp
     on urp.cdate = ur.cdate and
        urp.user_id = ur.user_id
where ur.user_id = ? and
      ur.cdate >= curdate() - interval 30 day
 group by ur.user_id, ur.cdate, ur.revenue;

注意事项:

= $id 表明您正在使用文字值修改查询字符串。 ? 表示 -- 使用参数。 使用有意义的表别名,这样查询更容易理解。 您需要left join 来保留第一个表中的所有行,即使第二个表中没有行。 因此,您需要处理可能产生的NULL 值。

【讨论】:

谢谢,SQL 工作正常,但仍有一些问题。当我以新用户身份登录时,我从表 user_revenue_publisher 中看到所有用户的总收入,为什么?在 php foreach 我有 foreach($result as $row) $final_revenue = $row['revenue'] + $row['total_revenue']; 我只需要在过去 30 天的同一天和 user_id 的一张表和第二张表的总收入。带有过去 30 天收入的经典图表。 我尝试使用: where ur.user_id =$id 和 urp.user_id=$id ,但这仅显示用户在第二个表 user_revenue_publisher 中有行的那一天,而不是其他有错误收入的日子。 我需要将这些查询合二为一:$result = $pdo->query("select * from user_revenue where user_id=$id AND `cdate` >= DATE(NOW() - INTERVAL 30 DAY)"); $result2 = $pdo->query("select * from user_revenue_pub where user_id=$id AND `cdate` >= DATE(NOW() - INTERVAL 30 DAY)");

以上是关于MySQL JOIN 2 个表并分别获取两个表的总和的主要内容,如果未能解决你的问题,请参考以下文章

mysql数据库表的查询

mysql update,2个表,把第一个表中所有满足条件的字段值(金额),加总到另一个表的总金额里

MySQL查询练习(45道)

MySQL INNER JOIN 3 个表的计数和总数

来自第二个表的 MySQL INNER JOIN (TOP10)

MYSQL 45道练习题