【问题标题】:How to obtaining remaining available days in a month for booking?如何获取一个月内剩余的可预订天数?
【发布时间】:2014-04-01 05:09:34
【问题描述】:

我有一个具有以下架构的插槽表

SlotId
FromDate
ToDate

我希望在给定月份中剩余的天数可用于预订时段。

为了清楚起见,我正在尝试检索给定月份的所有日期,而不是存储在数据库中的日期(因为这些日期已经预订)。

例如,如果一条记录有 FromDate 等于 2014-04-02 并且 ToDate 等于 2014-04-06 我期待以下结果:

2014-04-01
2014-04-07
...
2014-04-30

虽然我是在 PHP 中编写脚本,但我对完成此操作的查询并不好奇。

【问题讨论】:

  • 这些日期的数据类型是什么?
  • 我已将 DATE 指定为 FromDate 和 ToDate 的数据类型
  • 您在剩余的日子里每天都有预订吗?还是有例外情况?
  • 没有例外,整个月都可以使用

标签: mysql date


【解决方案1】:

所以在 mysql 中做这件事不是一件容易的事,但这里应该可以工作。这将获取任何给定月份中未预订的日期...有关工作示例,请参阅fiddle

SELECT *, union_month.day_date
FROM (
    SELECT 1 AS day_date 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 UNION ALL
    SELECT 12 UNION ALL
    SELECT 13 UNION ALL
    SELECT 14 UNION ALL
    SELECT 15 UNION ALL
    SELECT 16 UNION ALL
    SELECT 17 UNION ALL
    SELECT 18 UNION ALL
    SELECT 19 UNION ALL
    SELECT 20 UNION ALL
    SELECT 21 UNION ALL
    SELECT 22 UNION ALL
    SELECT 23 UNION ALL
    SELECT 24 UNION ALL
    SELECT 25 UNION ALL
    SELECT 26 UNION ALL
    SELECT 27 UNION ALL
    SELECT 28 UNION ALL
    SELECT 29 UNION ALL
    SELECT 30 UNION ALL
    SELECT 31
) AS union_month
LEFT JOIN myTable AS t ON union_month.day_date <> DAY(t.to_date) OR union_month.day_date <> DAY(t.from_date)
WHERE union_month.day_date <= DAY(LAST_DAY(t.to_date))
AND union_month.day_date NOT BETWEEN DAY(t.from_date) AND DAY(t.to_date)
GROUP BY union_month.day_date

对于一个月内的多个日期,将 WHERE 子句更改为此

WHERE
      union_month.day_date <= DAY(LAST_DAY(t.to_date))
      AND union_month.day_date not BETWEEN (select DAY(from_date) from myTable limit 0,1) AND (select DAY(to_date) from myTable limit 0,1)
      AND union_month.day_date not BETWEEN (select DAY(from_date) from myTable limit 1,1) AND (select DAY(to_date) from myTable limit 1,1)
      AND union_month.day_date not BETWEEN (select DAY(from_date) from myTable limit 2,1) AND (select DAY(to_date) from myTable limit 2,1)
GROUP BY union_month.day_date

在多个日期工作fiddle

【讨论】:

  • 当您在给定月份有多个记录时会发生什么?根据你的小提琴,如果你添加第二条记录它会失败。
  • 您可以为每个日期指定一个不介于两者之间的日期。但您需要知道入住/预订的数量。
  • 最好在给定日期的情况下使用另一种编程语言来执行此操作。或 create 要加入的日历表.... 最好的方法是在另一种编程语言中执行 while (start_date &lt;= from_date)while(to_date &lt;= end_date) ... end_date 和 start_date 可能是 sql 的一部分选择,其余的从那里很容易......如果OP愿意,我可以将其添加到答案中
  • 这正是我提到 to do what you wish with pure MySQL you would need to use a stored procedure/trigger 而你很快提到 no its possible... im doing it right now... 的原因,但是你还没有解决方案可以用纯 MySQL 做到这一点。
  • 如果你使用很可能消除硬代码依赖的触发器,可能会改进很多。
【解决方案2】:

您需要剩余天数或免费日期吗?

【讨论】:

  • 免费日期。我的意思是“除了存储在数据库中的日期(这些日期已经预订)之外,我想要给定月份的所有日期”
  • 如果您使用编程语言,您可以使用数组来完成。将预订日期存储在一个数组中,并将这些日期与特定月份的另一个日期数组进行比较。如果您只想使用替代查询。
  • 是的,但只是想知道是否有一种棘手的方法可以通过查询来完成此操作
【解决方案3】:

我已经试过了。愿它对你有所帮助。 您需要在循环中使用此查询。有一些变量。 在示例中,我只考虑了四月。你可以持续几个月。

SELECT distinct * FROM (SELECT DATE_ADD('2014-04-01', INTERVAL t4+t16+t64+t256+t1024 DAY) freedays  FROM 
(SELECT 0 t4    UNION ALL SELECT 1   UNION ALL SELECT 2   UNION ALL SELECT 3  ) t4,
(SELECT 0 t16   UNION ALL SELECT 4   UNION ALL SELECT 8   UNION ALL SELECT 12 ) t16,   
(SELECT 0 t64   UNION ALL SELECT 16  UNION ALL SELECT 32  UNION ALL SELECT 48 ) t64,      
(SELECT 0 t256  UNION ALL SELECT 64  UNION ALL SELECT 128 UNION ALL SELECT 192) t256,     
(SELECT 0 t1024 UNION ALL SELECT 256 UNION ALL SELECT 512 UNION ALL SELECT 768) t1024     
) b 
 WHERE freedays not between (select FrmDate from slotbooking limit 1) and (select ToDate from
  slotbooking limit 1) and freedays < '2014-04-30';

【讨论】:

  • 它可能并不完美,但有逻辑。你可以修改它。
  • what about multiple records along the month? 您的示例适用于单个记录,但在他的桌子上,他将在给定月份有多个预订日期,或者可能从上个月开始并部分进入当前月份。跨度>
  • @Prix 需要使用 counter 来获取 between 子句的 FrmDate 和 ToDate。
  • 您的回答原样,不会解决 OP 问题。然而,它确实部分回答了它。
  • @Prix 是的。这就是为什么我提到我的第一条评论。 :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多