查询我的多个日期范围分组

时间:2016-02-22 21:38:20

标签: mysql

我需要使用count和sum查询多个日期范围的数据,我正在寻找比我现在所做的更快的查询。
我有一个包含日期和金额的交易表。我需要提供一张表格,其中包含今天,昨天,本周,上周,本月,上个月的交易次数和总金额。目前我在做子查询,有更好的方法吗?

select  
(select count(date) from transactions where date between ({{today}})) as count_today,  
(select sum(amount) from transactions where date between ({{today}})) as amount_today,  
(select count(date) from transactions where date between ({{yesterday}})) as count_yesterday,  
(select sum(amount) from transactions where date between ({{yesterday}})) as amount_yesterday,  
(select count(date) from transactions where date between ({{thisweek}})) as count_thisweek,  
(select sum(amount) from transactions where date between ({{thisweek}})) as amount_thisweek,  
etc...

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

虽然你有一个标记的解决方案,我还有另一个可能会进一步使用MySQL变量来简化你的查询,所以你不必错误输入/计算日期等......

不是预先声明变量,而是可以将它们作为select语句内联,然后将它们用作另一个表中的列。由于它是作为单行创建的,因此没有笛卡尔结果。首先是查询,然后我将描述其上的计算。

KeyListener

现在,日期。由于@variables是按顺序编写的,因此您可以将其视为用于设置变量的内联程序。由于它们是预查询,因此它们首先完成,并且如前所述在查询的其余部分期间可用。首先,我正在处理任何" curdate()"只是在不考虑时间的情况下得到日期部分。从那里,减去1天(加-1)以获得昨天的开始。加1天即可获得明天。然后,本周的第一天是当前日期为+1 - 实际的星期几(您很快就会看到)。从一周的第一天开始添加7天以获得本周结束。最后,获取昨天(前一周结束时可能存在)或本周开始之间的最小日期。

select
      sum( if( t.date >= @today AND t.date < @tomorrow, 1, 0 )) as TodayCnt,
      sum( if( t.date >= @today AND t.date < @tomorrow, amount, 0 )) as TodayAmt,
      sum( if( t.date >= @yesterday AND t.date < @today, 1, 0 )) as YesterdayCnt,
      sum( if( t.date >= @yesterday AND t.date < @today, amount, 0 )) as YesterdayAmt,
      sum( if( t.date >= @FirstOfWeek AND t.date < @EndOfWeek, 1, 0 )) as WeekCnt,
      sum( if( t.date >= @FirstOfWeek AND t.date < @EndOfWeek, amount, 0 )) as WeekAmt
   from
      transations t,
   ( select @today := curdate(),
               @yesterday := date_add( @today, interval -1 day ),
               @tomorrow := date_add( @today, interval 1 day ),
               @FirstOfWeek := date_add( @today, interval +1 - dayofweek( @today) day ),
               @EndOfWeek := date_add( @FirstOfWeek, interval 7 day ),
               @minDate := least( @yesterday, @FirstOfWeek ) ) sqlvars
   where
          t.date >= @minDate
      AND t.date < @EndOfWeek

为什么我要截断日期剥离次数?为了简化&gt; = AND&lt;的SUM()条件。如果我说了一些日期=今天,如果您的交易有时间戳,该怎么办?然后你必须提取日期部分才有资格。通过这种方法,我可以说&#34;今天&#34;计数和金额是任何日期&gt; = 2月23日午夜12点和&lt; 2月24日午夜12点。这是所有时间包括2月23日至晚上11:59:59因此不到2月24日(明天)。

昨天的类似考虑是全包,但不包括任何&#34;今天&#34;是。同样适用于周范围。

最后WHERE子句正在寻找最早的日期作为范围,因此它不必在整个事务数据库中运行到最后。

最后,如果你想要前一周/周期的计数和总数,无论如何,你可以只是推断和改变

Now look at today for example... Feb 23rd.
Sun  Mon  Tue  Wed  Thu  Fri  Sat  Sun
21   22   23   24   25   26   27   28

Today = 23
Yesterday = 22
Tomorrow = 24
First of week = 23 + 1 = 24 - 3rd day of week = 21st
End of Week = 21st + 7 days = 28th.

如果查询在那个日期运行,计算将是AS。

类似的,如果你想改变一个月,你可以计算一个月中的第一个月到下个月的第一个月的总数。

希望您喜欢这种灵活的解决方案。

答案 1 :(得分:1)

是的,您可以在条件表达式上使用聚合函数,如下所示:

SELECT SUM(IF(date between ({{today}})), 1, 0) AS count_today
, SUM(IF(date between ({{today}})), amount, 0) AS amount_today
, ...