计算30天垃圾箱中的行数

sea*_*ieb 6 mysql select datediff count

我表中的每一行都有一个日期时间戳,我希望从现在起查询数据库,计算过去30天内的行数,前30天的行数等等.直到有30天的垃圾箱回到桌子的开头.

我已经成功地使用Python并进行了多次查询来执行此查询.但我几乎可以肯定它可以在一个MySQL查询中完成.

Phi*_*ost 3

没有存储过程、临时表,只有一个查询,以及给定日期列索引的高效执行计划:

select

  subdate(
    '2012-12-31',
    floor(dateDiff('2012-12-31', dateStampColumn) / 30) * 30 + 30 - 1
  ) as "period starting",

  subdate(
    '2012-12-31',
    floor(dateDiff('2012-12-31', dateStampColumn) / 30) * 30
  ) as "period ending",

  count(*)

from
  YOURTABLE
group by floor(dateDiff('2012-12-31', dateStampColumn) / 30);
Run Code Online (Sandbox Code Playgroud)

除了这个咒语之外,这里发生的事情应该是非常明显的:

floor(dateDiff('2012-12-31', dateStampColumn) / 30)
Run Code Online (Sandbox Code Playgroud)

该表达式出现多次,其计算结果为 30 天前的周期数dateStampColumnis。dateDiff返回以天为单位的差值,将其除以 30 得到 30 天的周期,并将其全部输入以将floor()其四舍五入为整数。一旦我们有了这个数字,我们就可以得到GROUP BY它,然后我们做一些数学运算,将这个数字转换回该期间的开始和结束日期。

如果您愿意,可以替换'2012-12-31'为。now()这是一些示例数据:

CREATE TABLE YOURTABLE
    (`Id` int, `dateStampColumn` datetime);

INSERT INTO YOURTABLE
    (`Id`, `dateStampColumn`)
VALUES
    (1, '2012-10-15 02:00:00'),
    (1, '2012-10-17 02:00:00'),
    (1, '2012-10-30 02:00:00'),
    (1, '2012-10-31 02:00:00'),
    (1, '2012-11-01 02:00:00'),
    (1, '2012-11-02 02:00:00'),
    (1, '2012-11-18 02:00:00'),
    (1, '2012-11-19 02:00:00'),
    (1, '2012-11-21 02:00:00'),
    (1, '2012-11-25 02:00:00'),
    (1, '2012-11-25 02:00:00'),
    (1, '2012-11-26 02:00:00'),
    (1, '2012-11-26 02:00:00'),
    (1, '2012-11-24 02:00:00'),
    (1, '2012-11-23 02:00:00'),
    (1, '2012-11-28 02:00:00'),
    (1, '2012-11-29 02:00:00'),
    (1, '2012-11-30 02:00:00'),
    (1, '2012-12-01 02:00:00'),
    (1, '2012-12-02 02:00:00'),
    (1, '2012-12-15 02:00:00'),
    (1, '2012-12-17 02:00:00'),
    (1, '2012-12-18 02:00:00'),
    (1, '2012-12-19 02:00:00'),
    (1, '2012-12-21 02:00:00'),
    (1, '2012-12-25 02:00:00'),
    (1, '2012-12-25 02:00:00'),
    (1, '2012-12-26 02:00:00'),
    (1, '2012-12-26 02:00:00'),
    (1, '2012-12-24 02:00:00'),
    (1, '2012-12-23 02:00:00'),
    (1, '2012-12-31 02:00:00'),
    (1, '2012-12-30 02:00:00'),
    (1, '2012-12-28 02:00:00'),
    (1, '2012-12-28 02:00:00'),
    (1, '2012-12-30 02:00:00');
Run Code Online (Sandbox Code Playgroud)

结果:

period starting     period ending   count(*)
2012-12-02          2012-12-31      17
2012-11-02          2012-12-01      14
2012-10-03          2012-11-01      5
Run Code Online (Sandbox Code Playgroud)

期间端点包括在内。

在SQL Fiddle中玩这个。

有一点潜在的愚蠢之处在于,任何 30 天的时间段内有零个匹配行都不会包含在结果中。如果您可以将其与周期表连接起来,那么就可以消除这种情况。然而,MySQL 没有像 PostgreSQL 的generate_series()这样的东西,所以你必须在你的应用程序中处理它或者尝试这个聪明的 hack