1

我想获取给定月份中每一天的统计数据。但是,如果一天在表中没有行,则它不会显示在结果中。如何包含没有数据的天数,并显示当前日期之前的所有天数?

这是我现在的查询:

SELECT DATE_FORMAT(FROM_UNIXTIME(timestamp), '%d'), COUNT(*)
FROM data
WHERE EXTRACT(MONTH FROM FROM_UNIXTIME(timestamp)) = 6
GROUP BY EXTRACT(DAY FROM FROM_UNIXTIME(timestamp))

所以如果我有

Row 1 | 01-06
Row 2 | 02-06
Row 3 | 03-06
Row 4 | 05-06
Row 5 | 05-06

(我将时间戳值更改为日/月日期只是为了解释)

它应该输出

01 | 1
02 | 1
03 | 1
04 | 0
05 | 2
06 | 0

...而不是忽略第 4 天和今天(第 6 天)。

4

3 回答 3

3

您将需要一个日历表在表单中执行某些操作

SELECT `date`, count(*)
FROM Input_Calendar c
LEFT JOIN Data d on c.date=d.date
GROUP BY `date`

我在我的数据库中保留了日历表的完整副本并使用 WHILE 循环来填充它,但您可以根据不同的解决方案即时填充一个以供使用,例如http://crazycoders.net/2012/03/在 mysql 中使用日历表/

于 2013-06-06T13:51:26.123 回答
1

在 MySQL 中,您可以使用 MySQL 变量(类似于内联编程值)。您可以根据需要设置并进行操作。

select
      dayofmonth( DynamicCalendar.CalendarDay ) as `Day`,
      count(*) as Entries
   from
      ( select
              @startDate := date_add( @startDate, interval 1 day ) CalendarDay
           from 
              ( select @startDate := '2013-05-31' ) sqlvars,
              AnyTableThatHasAsManyDaysYouExpectToReport
           limit
             6 ) DynamicCalendar
         LEFT JOIN Input_Calendar c
            on DynamicCalendar.CalendarDay = date( from_unixtime( c.date ))
   group by
      DynamicCalendar.CalendarDay

在上面的示例中,内部查询可以加入,正如名称所暗示的那样,您的数据库中的“任何表”至少有 X 条您试图为其生成的记录......在这种情况下,您只处理当前6 月份,只需要 6 条记录,但如果你想做一整年,只需确保“任何表”有 365 条记录(或更多)。

内部查询将通过将“@startDate”设置为 6 月 1 日(5 月 31 日)之前的一天开始。然后,通过仅拥有另一个表,将导致通过 6 条记录(生成报告的天数)的限制将每条记录加入到该变量(创建模拟的 for/next 循环)。所以现在,在查询记录时,开始日期不断增加 1 天......第一个记录结果在 6 月 1 日,下一个记录在 6 月 2 日,等等。

所以现在,您有一个模拟日历,其中有 6 条记录,日期从 6 月 1 日到 6 月 6 日。把它加入到您的“数据”表中,您已经通过加入来限定您的日期,并且只获得这些活动日期。我加入了来自 unix 时间的 DATE(),因为您关心 6 月 1 日发生的任何事情,并且 6 月 1 日 @ 12:00:00AM 与 6 月 1 日 @ 8:45am 不同,因此仅匹配日期部分,它们应该保持在适当的分组中。

您可以通过将内部 '2013-05-31' 更改为某些 MySQL Date 函数来扩展此答案,以获取上个月的最后一天,并根据您当前月份的任何一天进行限制,因此这些并不难-编码。

于 2013-06-06T14:11:08.383 回答
0

创建时间维度。这是一个标准的 OLAP 报告技巧。不过,您不需要多维数据集来执行 OLAP 技巧。只需在 Internet 上找到一个脚本即可生成日历表并加入该表。

另外,我认为您的查询缺少 WHERE 子句。

其他有用的技巧包括创建一个“Tally”表,它是从 1 到 N 的数字列表,其中 N 通常是数据库管理系统上 bigint 的最大值。

这里没有提供代码,因为我不是 MySQL 专家。

伪代码是:

Select * from Data left join TimeDimension on data.date = timedimension.date

于 2013-06-06T13:49:35.947 回答