【问题标题】:Getting sum of duplicated date entries from last month, week, day获取上个月、一周、一天的重复日期条目的总和
【发布时间】:2012-04-05 15:10:11
【问题描述】:

我有一个包含 3 列的表:idupdated_atclick_sum

许多行具有完全相同的updated_at 值,这使得很难简单地检索数据order by updated_at 并在图表中显示总和。 由于同一日期有多个总和,这会影响图表。

我试图实现的是获得以下输出:

 update_at | click_sum
-----------+-----------
   date1   |    100
   date2   |     3
   date3   |    235
   date4   |    231

可选地,只有上个月、上一周或上一天AND 的日期,而不仅仅是NOW() - 1 月份的日期。

我构建的当前查询非常大,而且效果不佳。 它按日期分组(没有出现重复的日期)和SUM()s 正确点击,但定义日期的时间(上个月、一周、一天)似乎无法正常工作。

查询:($interval 代表MONTHDAYSECONDWEEK

SELECT d.updated_at, SUM(d.clicks_sum) AS click_sum
FROM aggregated_clicks d
JOIN 
(
     SELECT c.id, MAX(StartOfChains.updated_at) AS ChainStartTime
     FROM aggregated_clicks c
     JOIN 
     (
         SELECT DISTINCT a.updated_at
         FROM aggregated_clicks a
         LEFT JOIN aggregated_clicks b ON (b.updated_at >= a.updated_at - INTERVAL 1 DAY AND b.updated_at < a.updated_at)
         WHERE b.updated_at IS NULL
      ) StartOfChains  ON c.updated_at >= StartOfChains.updated_at
     GROUP BY c.id
) GroupingQuery
ON d.id = GroupingQuery.id
WHERE GroupingQuery.ChainStartTime >= DATE_SUB(NOW(), INTERVAL 1 $interval)
GROUP BY GroupingQuery.ChainStartTime
ORDER BY GroupingQuery.ChainStartTime ASC

【问题讨论】:

  • 我不明白你想要的结果是什么。你想要每个id 一行吗?每个updated_at 一行?再加上,你想要一些东西的总和?
  • 您能否提供示例数据以产生上述预期输出?谢谢
  • 假设 id 是唯一的,您想要同一日期的所有实例的 click_sum 的总和,还是只想要特定日期的“最新”行?
  • @MattFenwick 我想要每个唯一的 updated_at 一行 + 具有该 updated_at 的所有 updated_at 行的 SUM(click_sum)

标签: php mysql sql


【解决方案1】:

也许我对您的问题的性质(以及它所引用的表格)假设太多,但我认为这可以比您显示的查询更简单。

计算最近完成的月份并不难。

从知道当前月份的第一个日期开始 -- 使用这个:

date_sub(curdate(), interval (extract(day from curdate())-1) day)

要知道上个月的第一天,请使用:

date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month)

因此,如果您只想获取中间几天的总和 - 即最近完成的月份,请使用:

select updated_at, sum(click_sum) from aggregated_clicks
  where updated_at >= date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month)
    and updated_at < date_sub(curdate(), interval (extract(day from curdate())-1) day)
  group by updated_at;

计算最近完成的一周同样容易。此示例将假定星期天到星期六。

由于 ODBC 标准定义日期数字的方式,很容易找到上一周的结束(星期六):

date_sub(curdate(), interval dayofweek(curdate()) day)

那一周的开始(星期日)是在那之前的六天:

date_sub(curdate(), interval (dayofweek(curdate())+6) day)

因此,如果您只想获取中间几天的总和 - 即最近完成的一周,请使用:

select updated_at, sum(click_sum) from aggregated_clicks
  where updated_at >= date_sub(curdate(), interval (dayofweek(curdate())+6) day)
    and updated_at <= date_sub(curdate(), interval dayofweek(curdate()) day)
  group by updated_at;

当然,根据最近完成的日期计算非常容易。

要获取前一天的日期,请使用:

date_sub(curdate(), interval 1 day)

所以如果你想要昨天的总和,使用这个:

select updated_at, sum(click_sum) from aggregated_clicks
  where updated_at = date_sub(curdate(), interval 1 day)
  group by updated_at;

注意:我已经使用 MySQL 5.1 YMMV 测试了这些查询。

---------

更新:由于日期列是日期时间,只需将我的查询中对updated_at 的所有引用更改为date(updated_at),如下所示:

月份情况:

select date(updated_at), sum(click_sum) from aggregated_clicks
  where date(updated_at) >= date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month)
    and date(updated_at) < date_sub(curdate(), interval (extract(day from curdate())-1) day)
  group by date(updated_at);

周案例:

select date(updated_at), sum(click_sum) from aggregated_clicks
  where date(updated_at) >= date_sub(curdate(), interval (dayofweek(curdate())+6) day)
    and date(updated_at) <= date_sub(curdate(), interval dayofweek(curdate()) day)
  group by date(updated_at);

昨天的案例:

select date(updated_at), sum(click_sum) from aggregated_clicks
  where date(updated_at) = date_sub(curdate(), interval 1 day)
  group by date(updated_at);

【讨论】:

  • 我会在今天运行这些查询,如果我们的服务器会回来 (o.O) 并给您即时反馈。
  • 测试过了。问题是您会为每个唯一日期获得一个新的结果行。日期采用标准日期格式,包括分钟和秒。但我希望 1 天的所有 click_sums 成为一行,而不是每个日期相差几分钟的新行。
  • 日期列的数据类型是什么?
  • select updated_at, sum(clicks_sum) from aggregated_clicks where updated_at >= date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month) 和updated_at
  • 查看编辑——只需将原始查询中对updated_at的所有引用更改为date(updated_at)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 2014-01-20
  • 2010-10-10
  • 1970-01-01
  • 2013-05-28
  • 2019-05-14
相关资源
最近更新 更多