【问题标题】:Combine two select statements grouped by date returning two columns of data组合两个按日期分组的选择语句,返回两列数据
【发布时间】:2017-04-09 01:57:22
【问题描述】:

这似乎是一项简单的任务,但我的基本 sql 知识让我失望了,因为我还在学习。

基本上,我正在尝试结合:

SELECT DATE(created) DATE, COUNT(DISTINCT created) newpost FROM surveys
WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY GROUP BY DATE(created);

SELECT DATE(TIMESTAMP) DATE,subs FROM trafficstats
WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY;

进入一个查询,该查询将按日期分组的数据返回到另外两列 - newpostssubs

我试过使用UNION,它似乎并没有给我想要的输出。它将数据合并为一列(newpost),也没有按日期分组。

我对编写MySQL 查询还是很陌生,我尝试寻找答案无济于事。希望在这里寻求比我聪明的人的知识。

【问题讨论】:

  • 您能否创建一个简单的最小数据视图,说明您拥有什么以及您对结果的期望?因为正如您提到的,这两个查询有 1 个公共字段 DATE 和两个不同的字段 newpostsubs。那么如果将这两个查询结合起来,是否意味着第一个查询的记录都将有空的subs 字段,而第二个查询的记录都将有空的newpost 字段?

标签: mysql


【解决方案1】:

你可以使用 JOIN

    select t1.DATE, t1.newpost, t2.subs 
    from (
      SELECT DATE(created) DATE, COUNT(DISTINCT created) newpost 
      FROM surveys 
      WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
      AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY 
      GROUP BY DATE(created)
    ) t1
    left join  (
      SELECT DATE(TIMESTAMP) DATE, subs 
      FROM trafficstats 
      WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
      AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY
    ) t2 on t1.DATE = t2.DATE

【讨论】:

    【解决方案2】:

    我猜你希望每个不同的日期有一行,显示两个不同的计数值。

    这种查询比初看起来要复杂一些,因为这两个摘要查询可能有不同的日期集。

    因此,您需要从产生所有可能感兴趣的日期的子查询开始。然后,您需要将每个摘要查询 LEFT JOIN 加入其中。您必须使用 LEFT JOIN 而不是普通的内部 JOIN,因为当连接右侧的行与左侧的任何行都不匹配时,LEFT JOIN 不会抑制来自右侧的行。

    这里是:

    你所有的日期。请注意UNION 操作是一个集合(重复删除)联合操作。

                SELECT DISTINCT DATE(created) DATE FROM newpost
                 WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
                  AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY
                 UNION
                SELECT DISTINCT DATE(TIMESTAMP) DATE FROM trafficstats 
                 WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
                   AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY
    

    然后您需要两个摘要子查询。第一个是这个。请注意,我将COUNT(DISTINCT created) 更改为COUNT(*),因为我不明白DISTINCT 背后的逻辑。一个帖子可以有多行吗?你用时间戳区分它们吗?如果每个帖子都有一行,您应该COUNT(*)

               SELECT DATE(created), COUNT(*) newposts
                 FROM newpost
                GROUP BY DATE(created)
    

    第二个总结是这样的。再次,我数了行数。

               SELECT DATE(TIMESTAMP), COUNT(*) subs
                 FROM trafficstats
                GROUP BY DATE(TIMESTAMP)
    

    最后,像这样加入这三个子查询。您从第一个子查询中获取日期,从后两个子查询中获取按日期汇总的信息。

         SELECT dates.DATE, posts.newposts, subs.subs
           FROM ( /* date subquery */ ) dates
           LEFT JOIN ( /* posts subquery */ ) posts ON dates.DATE = posts.DATE
           LEFT JOIN ( /* subs subquery */ ) subs ON dates.DATE = subs.DATE
          ORDER BY dates.DATE
    

    把它们放在一起:

         SELECT dates.DATE, posts.newposts, subs.subs
           FROM (
                SELECT DISTINCT DATE(created) DATE FROM newpost
                 WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
                  AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY
                 UNION
                SELECT DATE(TIMESTAMP) DATE FROM trafficstats 
                 WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
                   AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY
                ) dates
           LEFT JOIN (
                    SELECT DATE(created), COUNT(*) newposts
                      FROM newpost
                     GROUP BY DATE(created)
                ) posts ON dates.DATE = posts.DATE
           LEFT JOIN (
                       SELECT DATE(TIMESTAMP), COUNT(*) subs
                         FROM trafficstats
                        GROUP BY DATE(TIMESTAMP)
                ) subs ON dates.DATE = subs.DATE
          ORDER BY dates.DATE
    

    【讨论】:

    • 我需要的结果是按日期分组的一行,一列用于新帖子计数,一列用于订阅计数。好消息是两个表之间的所有日期都匹配,因此它不应该因为空值而删除任何数据。
    猜你喜欢
    • 2015-11-09
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 2020-07-19
    • 2011-02-16
    • 1970-01-01
    相关资源
    最近更新 更多