【问题标题】:SQL to sum bookings between date rangesSQL 对日期范围之间的预订求和
【发布时间】:2019-03-04 09:25:31
【问题描述】:

我的桌子上摆满了如下所示的预订:

| 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 语句,但就是无法破解。

感谢任何帮助。

【问题讨论】:

  • 我已经更新了问题的格式并添加了一些新的文本来进一步阐明问题。
  • 如果您不创建一个“日历表”,您将无法“破解”它,它将作为您所有日子的主表,您将从中加入您的按天预订表和团体。这里和网上都有很多例子

标签: mysql sql


【解决方案1】:

虽然您在 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 表,最后使用@987654323 @ 你得到每个日期的数量总和。

【讨论】:

    【解决方案2】:

    最大的问题是生成日期。在 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;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-19
      • 2017-12-20
      • 2021-11-15
      • 2014-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多