SQL汇总日期范围之间的预订

时间:2019-03-04 09:25:31

标签: mysql sql

我有一张桌子,上面满是这样的预订:

| ID | START_DATETIME      | END_DATETIME        | QUANTITY |
+-----------------------------------------------------------+
| 1  | 2019-03-01 12:00:00 | 2019-03-04 12:00:00 |     3    |
| 2  | 2019-03-02 12:00:00 | 2019-03-03 12:00:00 |     1    |
| 3  | 2019-03-03 12:00:00 | 2019-03-04 12:00:00 |     1    |
| 4  | 2019-03-04 12:00:00 | 2019-03-05 12:00:00 |     2    |

我需要获取给定日期范围内每一天的数量。

以下是给定日期范围的示例:

2019-03-01 to 2019-03-06

这是预期的结果:

| DATE        | QUANTITY | 
+------------------------+
| 2019-03-01  |     3    |
| 2019-03-02  |     4    |
| 2019-03-03  |     5    |
| 2019-03-04  |     6    |
| 2019-03-05  |     2    |
| 2019-03-06  |     0    |

以下是如何计算结果的说明:

  • 2019-03-01是预订1数量的总和
  • 2019-03-02是预订1和2数量的总和
  • 2019-03-03是预订1和2和3数量的总和
  • 2019-03-04是预订1、3和4的数量之和
  • 2019-03-05是预订4数量的总和
  • 2019-03-06没有预订

我尝试了各种类型的SQL语句,但无法破解。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

尽管您正在寻找MySql中的解决方案,但我为您提供了一个在SQL Server中执行相同操作的代码,希望对您有所帮助:

WITH Dates AS (
        SELECT
         [Date] = CONVERT(DATETIME,'2019-03-01')
        UNION ALL
        SELECT
         [Date] = DATEADD(DAY, 1, [Date])
        FROM
         Dates
        WHERE
         Date < '2019-03-06'
)



  Select cast(d.Date as date), IsNull(Sum(b.QUANTITY), 0) 
   from Dates d left join Bookings b
   on
    d.Date >= cast(b.START_DATETIME as date) 
    and  
    d.Date <= cast(b.END_DATETIME as date)
   group by d.Date

可以看出,首先您需要生成日期范围,然后将其加入Bookings表中,最后使用 Group By 您将获得每个日期的数量总和。

答案 1 :(得分:0)

最大的问题是生成日期。在MySQL 8+中,您可以使用递归CTE。否则,只需列出值:

select d.dte,
       (select sum(b.quantity)
        from bookings b
        where b.start_datetime <= d.dte + interval 1 day and
              b.end_datetime >= d.dte
       ) as quantity
from ((select date('2019-03-01') as dte union all
      (select date('2019-03-02') as dte union all
      (select date('2019-03-03') as dte union all
      (select date('2019-03-04') as dte union all
      (select date('2019-03-05') as dte union all
      (select date('2019-03-06') as dte 
     ) d;

这对于几个日期来说已经足够好了。如果您的电话号码更大,建议您使用日历表或数字表。