【问题标题】:How can I make an sql query return a row for every day in a range of dates in mysql?如何使 sql 查询在 mysql 的日期范围内每天返回一行?
【发布时间】:2017-06-22 21:20:12
【问题描述】:

如何让 sql 查询在 mysql 中的某个日期范围内为每一天返回一行?

我有一个具有这种结构的工作表:

job_id  |   station_id  |   start_date  |   end_date    |
--------+---------------+---------------+---------------+
    1   |   1           |   2017-06-01  |   2017-06-02  |
    2   |   2           |   2017-06-01  |   2017-06-03  |
    3   |   1           |   2017-06-02  |   2017-06-04  |
    4   |   4           |   2017-06-01  |   2017-06-02  |
    5   |   2           |   2017-06-04  |   2017-06-05  |
    6   |   1           |   2017-06-06  |   2017-06-08  |
    7   |   3           |   2017-06-01  |   2017-06-02  |

还有一个站台:

station_id |    type    |
-----------+------------|
    1      |    1       |
    2      |    1       |
    3      |    2       |
    4      |    2       |
    5      |    2       |

如果我想知道在 2017 年 6 月 1 日使用了多少个类型 2 的站点,我可以很容易地做到这一点:

SELECT COUNT(job_id)
FROM jobs
WHERE start_date <= '2017-06-01'
AND  end_date > '2017-06-01'
AND station_id IN (SELECT station_id FROM station WHERE type = 2);

这个例子告诉我们有 2 个站(3 和 4)正在使用:

+-------------+
|COUNT(job_id)|
+-------------+
|           2 |
+-------------+

但是,我希望这样可以为日期范围内的每一天返回一行

到目前为止,我已经用一个多次运行第一个查询的 python 脚本解决了这个问题,有没有办法直接用 mysql 来解决这个问题?

编辑:根据 user1960808 的要求,范围 2017-06-01 2017-06-03 和类型 2 的预期结果将是:

+-----------+-------------+
|   date    |COUNT(job_id)|
+-----------+-------------+
|2017-06-01 |   2         |
|2017-06-02 |   0         |
|2017-06-03 |   0         |
+-----------+-------------+

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    也许最简单的方法是生成范围:

    select d.dte, count(job_id)
    from (select '2017-06-01' as dte union all
          select '2017-06-02' as dte 
         ) d left join
         jobs j
         on j.start_date <= d.dte and j.end_date > d.dte
    where j.station_id in (select station_id from station s where s.type = 2)
    group by d.dte;
    

    如果您有很多约会,这不是最有效的解决方案。

    【讨论】:

    • 感谢您的帮助,这让我更接近我的需要。但是,如果我正确理解这一点,则必须分别写下每个日期。我正在寻找可以让我指定初始日期和最终日期并让 mysql 生成日期的东西,这就是我当前使用 python 的解决方案所做的。用mysql不可能吗?
    • @user1090729 。 . .如果您有Calendar 表,则可以使用子查询来生成日期。
    • 我没有,但我知道它有什么帮助。你认为这会是最好的解决方案吗? (我假设日历表只是一个常规表,其中包含每个日期的一行,如果还有其他问题,请纠正我)
    【解决方案2】:

    如果您可以创建如下 url 中提到的整数表,那么我认为可以通过以下查询来实现。

    https://www.xaprb.com/blog/2005/12/07/the-integers-table/

    创建整数表后查询

    SELECT job_id,station_id,start_date + INTERVAL i DAY, start_date,end_date
    FROM job
    INNER JOIN integers
           ON i <= DATEDIFF(end_date,start_date)
    AND station_id IN (SELECT station_id FROM station WHERE type = 2);
    

    【讨论】:

      【解决方案3】:

      检查一下

      DELIMITER $$
      
      Create Procedure GetJobRunningCount(dStartDate datetime,dEndDate datetime,dType int)
      Begin
      
        DROP TABLE IF EXISTS CountSummary;
        CREATE TEMPORARY TABLE CountSummary(SelectedDate date,Count int);
      
      
        While (dStartDate<=dEndDate) do
      
        insert into CountSummary(SelectedDate,Count)
          SELECT dStartDate,COUNT(1)
      FROM jobs jo
      inner join station st on(st.station_id=jo.station_id and type=dType )
      WHERE start_date <= dStartDate
      AND  end_date > dStartDate;
      
      
       set dStartDate=Date_add(dStartDate,interval 1 Day);
      
         End while;
      
         select * from CountSummary;
      
      END$$
      DELIMITER ;
      
      call GetJobRunningCount('2017-06-01','2017-06-08',2)
      

      【讨论】:

      • 我想明白,这不是只适用于今天吗?
      • 我明白了,我正在寻找可以指定两个日期的东西,它会为范围内的每一天返回一行。
      • 那么你可以使用你的日期来代替 date(now())。
      • 是的,完全正确。但问题是,如何在某个日期范围内执行此操作,而不是每次只有一个日期。
      • 请发送您的输出样本。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 2014-11-01
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多