固定日期范围之间的 MySQL 记录

Posted

技术标签:

【中文标题】固定日期范围之间的 MySQL 记录【英文标题】:MySQL record between fixed date range 【发布时间】:2018-04-26 19:45:01 【问题描述】:

我有一个使用 CodeIgniter 3 构建的小型应用程序,需要执行一个将转换为 Chart.js 的报告。该报告应以年度为基础,但在每个月的特定日期。要求是所有数据计数必须是每月第 4 到第 3 个月。像这样:

例如,1 月报告将是从 1 月 4 日到 2 月 3 日、2 月 4 日到 3 月 3 日……等等。

我创建了一个 mysql 查询,但我不知道如何获取日期。我的查询如下:

SELECT DATE_FORMAT(odd_date_created, '%Y') as 'year',
DATE_FORMAT(odd_date_created, '%m') as 'month',
COUNT(odd_id) as 'total', status
FROM odd_data 
WHERE status = $id and 
GROUP BY DATE_FORMAT(odd_date_created, '%Y%m'), status

我是 MySQl 的新手。有人可以帮我解决这个问题。我被困在哪里应该将日期查询放在哪里。

【问题讨论】:

有时使用日期跨度/范围作为 unix 时间戳更容易。如果您的字段是日期时间,MySQL 有UNIX_TIMESTAMP。然后 php 使用 mktime 轻松制作特定日期的时间戳。 严格地在 mysql 中,如果日期不整齐地位于月份边界上,您将无法轻松地分出日期。您最好使用 WHERE date_field BETWEEN '2017-11-03' AND '2017-12-03' 发出 12 个查询,然后在您的应用程序中组合结果。 【参考方案1】:

首先我要提醒你,当你来加入你的数据时,不要将“之间”与以下一起使用,而是使用这种方法data.date >= r.period_start_dt and data.date < r.period_end_dt

其次,我假设您的数据确实有日期或时间戳,并且将落在以下计算范围之间:

set @year :=2017;

select
       *
from (
        select 
               start_dt + INTERVAL m.n MONTH     period_start_dt
             , start_dt + INTERVAL m.n + 1 MONTH period_end_dt
        from (
               select str_to_date(concat(@year,'-01-04'),'%Y-%m-%d') start_dt ) seed
        cross join (select 0 n union all
                    select 1 union all
                    select 2 union all
                    select 3 union all
                    select 4 union all
                    select 5 union all
                    select 6 union all
                    select 7 union all
                    select 8 union all
                    select 9 union all
                    select 10 union all
                    select 11
                   ) m
     ) r
## LEFT JOIN YOUR DATA
## ON data.date >= r.period_start_dt and data.date < r.period_end_dt

示例范围:(在此演示中生成您自己的:http://rextester.com/CHTKSA95303)

nb dd.mm.yyyy (.de format)
+----+---------------------+---------------------+
|    |   period_start_dt   |    period_end_dt    |
+----+---------------------+---------------------+
|  1 | 04.01.2017 00:00:00 | 04.02.2017 00:00:00 |
|  2 | 04.02.2017 00:00:00 | 04.03.2017 00:00:00 |
|  3 | 04.03.2017 00:00:00 | 04.04.2017 00:00:00 |
|  4 | 04.04.2017 00:00:00 | 04.05.2017 00:00:00 |
|  5 | 04.05.2017 00:00:00 | 04.06.2017 00:00:00 |
|  6 | 04.06.2017 00:00:00 | 04.07.2017 00:00:00 |
|  7 | 04.07.2017 00:00:00 | 04.08.2017 00:00:00 |
|  8 | 04.08.2017 00:00:00 | 04.09.2017 00:00:00 |
|  9 | 04.09.2017 00:00:00 | 04.10.2017 00:00:00 |
| 10 | 04.10.2017 00:00:00 | 04.11.2017 00:00:00 |
| 11 | 04.11.2017 00:00:00 | 04.12.2017 00:00:00 |
| 12 | 04.12.2017 00:00:00 | 04.01.2018 00:00:00 |
+----+---------------------+---------------------+

【讨论】:

【参考方案2】:

鉴于规范,我想我会想作弊...从日期中减去 3 天。这样做,1 月 4 日支持到 1 月 1 日,2 月 3 日支持到 1 月 31 日......所以这些都以 1 月结束。

  SELECT DATE_FORMAT(odd_date_created + INTERVAL -3 DAY, '%Y') AS `year`
       , DATE_FORMAT(odd_date_created + INTERVAL -3 DAY, '%m') AS `month`
       , ...
    FROM ...

   GROUP
      BY DATE_FORMAT(odd_date_created + INTERVAL -3 DAY, '%Y')
       , DATE_FORMAT(odd_date_created + INTERVAL -3 DAY, '%m')

如果有奇怪的范围......如果它不总是第 4 个和第 3 个。

【讨论】:

我已经尝试过您的解决方案,它运行良好,但现在我的客户要求它能够根据年份进行过滤。我该怎么办呢。 “按年份过滤”的要求作为规范含糊不清。提供示例数据和预期数据是说明规范的好方法。没有这个,我们只是猜测。也许我们所追求的只是添加HAVING DATE_FORMAT(odd_date_created + INTERVAL -3 DAY,'%Y') = '2017' 或者我们想在 WHERE 子句中添加条件来限制行...AND odd_date_created &gt;= '2017-01-03' AND odd_date_created &lt; '2018-01-03'。我们可以使用表达式代替文字值。 DATE_FORMAT(NOW(),'%Y-%m-03') + INTERVAL -12 MONTH 它有效。你我的救命恩人。万分感激。谢谢@spencer7593 第一个选项添加“HAVING”条件,这就是我要找的。​​span>

以上是关于固定日期范围之间的 MySQL 记录的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:查找日期范围之间的缺失日期

3个日期范围之间的Mysql查询

MySql分区表 - 使用PK的日期范围之间选择与日期IN(...)子句相比非常慢

MySQL:开始日期和结束日期之间的日期的 IN 子句?

MySQL:选择两个日期范围内的所有数据

记录之间的 SQL Server 日期时间范围