如何从两个不同的表中获取两个不同列的总和并将它们分组

时间:2020-05-29 14:52:53

标签: mysql sql aggregate-functions

我有两个表,我想在两个表之间执行联接并按日期将它们分组

表1是fb_data

id  name created_at           revenue
1   as   2020-05-29 19:30:54  5
2   as   2020-05-28 19:30:54  10
3   ad   2020-05-29 19:31:42  6     
4  ad    2020-05-28 19:31:54 65
5  as    2020-05-29 19:32:10 7
6  ad    2020-05-28 19:31:54 5

表2是google_data

id name   created_at           sessions
1  as     2020-05-29 19:38:32    5 
2  ad     2020-05-29 19:38:41    10
3  as      2020-05-29 19:38:49   7 
4  as      2020-05-28 19:39:02   6
5  ad     2020-05-28 19:39:13   8
6  ad    2020-05-28 19:41:41   13

现在我要按名称连接两列,然后按created_at将它们分组。像这样

Name , date(created_at) as date , sum(fb_data.revenue) , sum(google_data.revenue)

我有一个sql查询,但是没有给出我期望的结果

select gd.name,fb.total_revenue,fb.created_at,gd.total_sessions
from (select date(fb_data.created_at) as created_at, sum(fb_data.revenue) as total_revenue, name
      from fb_data
      group by date(fb_data.created_at), name) fb,
     (select date(google_data.created_at) as created_at, sum(google_data.session) as total_sessions, name
      from google_data
      group by name, date(google_data.created_at)) as gd
      where fb.name = gd.name
      group by  gd.name,fb.name,fb.created_at,gd.total_sessions

我得到的结果是

Name total_revenue   created_at     total_sessions
as   12              2020-05-29     12             
as   12              2020-05-29     6
as   10              2020-05-28     12
as   10              2020-05-28     6    
ad   6               2020-05-29     10
ad   6              2020-05-29      21
ad  70             2020-05-28       10
ad  70             2020-05-28      21

我期望的结果是

name  total_revenue   created_at total_sessions
as    12              2020-05-29   12 
as    10              2020-05-28   6
ad    6               2020-05-29   10
ad    70              2020-05-28   21

4 个答案:

答案 0 :(得分:1)

请在下面的查询中使用

select gd.name,fb.total_revenue,fb.created_at, max(gd.total_sessions)
from (select date(fb_data.created_at) as created_at, sum(fb_data.revenue) as 
total_revenue, name
  from fb_data
  group by date(fb_data.created_at), name) fb,
 (select date(google_data.created_at) as created_at, sum(google_data.session) as 
total_sessions, name
  from google_data
  group by name, date(google_data.created_at)) as gd
  where fb.name = gd.name
  group by  gd.name,fb.name,fb.created_at;

答案 1 :(得分:1)

这个问题比乍看起来要难一些。

您需要加入三个子查询,每个子查询的名称和日期各占一行。

第一个子查询为您提供所有可能的名称和日期。之所以需要这个,是因为您的两个详细信息文件之一可能缺少另一个包含的名称/日期组合

        SELECT DISTINCT name, created_at
          FROM (
             SELECT name, DATE(created_at) created_at FROM fb
              UNION
             SELECT name, DATE(created_at) created_at  FROM gg
            ) a

您的第二个子查询获取每个名称/日期的会话计数。

             SELECT name, 
                    DATE(CREATED_AT) created_at, 
                    SUM(sessions) sessions
               FROM gg
              GROUP BY name, DATE(created_at)

第三个收入相同。

             SELECT name, 
                    DATE(CREATED_AT) created_at, 
                    SUM(revenue) revenue
               FROM fb
              GROUP BY name, DATE(created_at)

然后您将第二个和第三个子查询左联接到第一个子查询。

SELECT items.name, items.created_at, sess.sessions, rev.revenue
  FROM (first subquery) items
  LEFT JOIN (second subquery) sess ON items.name = sess.name
                                 AND items.created_at = sess.created_at
  LEFT JOIN (third subquery) rev ON items.name = rev.name
                                AND items.created_at = rev.created_at

一起,你明白了。

SELECT items.name, items.created_at, sess.sessions, rev.revenue
  FROM (SELECT DISTINCT name, created_at
          FROM (
             SELECT name, DATE(created_at) created_at FROM fb
              UNION
             SELECT name, DATE(created_at) created_at  FROM gg
            ) a
       ) items
  LEFT JOIN (SELECT name, 
                    DATE(CREATED_AT) created_at, 
                    SUM(sessions) sessions
               FROM gg
              GROUP BY name, DATE(created_at)
            ) sess ON items.name = sess.name
                  AND items.created_at = sess.created_at
  LEFT JOIN (SELECT name, 
                    DATE(CREATED_AT) created_at, 
                    SUM(revenue) revenue
               FROM fb
              GROUP BY name, DATE(created_at)
            ) rev ON items.name = rev.name
                  AND items.created_at = rev.created_at

https://www.db-fiddle.com/f/hiAKaSDWn1FuUufF3oLbgZ/0

答案 2 :(得分:1)

尝试以下查询:

SELECT t.name, t.total_revenue, t.created_at, t2.total_sessions
FROM
  (SELECT name, date(created_at) created_at, sum(revenue) total_revenue
   FROM fb_data
   GROUP BY name,
            date(created_at)) t
INNER JOIN
  (SELECT name, date(created_at) created_at, sum(sessions) total_sessions
   FROM google_data
   GROUP BY name,
            date(created_at)) t2 ON t2.created_at = t.created_at
AND t2.name = t.name;

答案 3 :(得分:0)

您可以在下面使用简单的查询。它给出了预期的结果:

select aa.name,aa.created, sum(ses), sum(rev)  
from 
    (select fb_data.name, date(created_at) as created, sum(revenue) as rev, 0 as ses
    from fb_data group by fb_data.name,date(created_at) 
    UNION
    select google_data.name, date(created_at) as created, 0 as rev, sum(sessions) as ses
    from google_data group by google_data.name,date(created_at)
    ) as aa 
group by name,created;

检查结果: https://www.db-fiddle.com/f/7wpGKon7SH58HNF7Q4SuFH/1

相关问题