【问题标题】:Find elements between two dates and group them查找两个日期之间的元素并将它们分组
【发布时间】:2018-06-12 13:27:30
【问题描述】:

我有这张桌子:

___Bookings:

|--------|------------|--------------|------------|------------|
| BOO_Id | BOO_RoomId | BOO_ClientId | BOO_DateCI | BOO_DateCO |
|--------|------------|--------------|------------|------------|
| 1      | 9          | 45           | 2018-01-02 | 2018-01-03 |
| 2      | 4          | 46           | 2017-12-30 | 2018-01-07 |
| 3      | 3          | 2            | 2018-12-31 | 2018-01-01 |
| 4      | 9          | 98           | 2018-01-05 | 2018-01-10 |
|--------|------------|--------------|------------|------------|

我希望每天显示出发、到达或内部的预订。

所需的输出应该是这样的:

2017-12-30  =  Booking #2 in arrival.
2017-12-31  =  Booking #3 in arrival.
            =  Booking #1 in arrival.
            =  Booking #2 in house.
2018-01-01  =  Booking #3 in departure.
            =  Booking #2 in house.
2018-01-02  =  Booking #1 in arrival.
            =  Booking #2 in house.
2018-01-03  =  Booking #1 in departure.
            =  Booking #2 in house.
2018-01-04  =  Booking #2 in house.
2018-01-05  =  Booking #4 in arrival.
            =  Booking #2 in house.
2018-01-06  =  Booking #2 in house.
            =  Booking #4 in house.
2018-01-07  =  Booking #2 in departure.
            =  Booking #4 in house.
2018-01-08  =  Booking #4 in house.
2018-01-09  =  Booking #4 in house.
2018-01-10  =  Booking #4 in departure.

我已经尝试过的:

SELECT *,
    CASE 
      WHEN BOO_DateCI = '2017-04-01' THEN 'In Arrival'
      WHEN BOO_DateCO = '2017-04-30' THEN 'In Departure'
      WHEN '2017-04-01' > BOO_DateCI AND '2017-04-01' < BOO_DateCO THEN 'In House'
    END
FROM ___Bookings
WHERE BOO_DateCI = '2017-04-01'
OR BOO_DateCO = '2017-04-30'
OR '2017-04-01' BETWEEN BOO_DateCI AND BOO_DateCO;

但我无法获得in house 预订,也无法根据arrivaldeparturein-house 的状态对预订进行分组。

【问题讨论】:

  • 您的数据库中的预订状态在哪里?
  • 状态由'BOO_DateCI'和'BOO_DateCO'决定。如果today == BOO_DateCI => '到达'。如果today == BOO_DateCO => '出发'。如果today &gt; BOO_DateCI today &lt; BOO_DateCO => '在内部'。

标签: php mysql sql


【解决方案1】:

您缺少的是日期列表,如果您在数据库中没有专门的日期维度,您可以像这样手动完成:

DECLARE @start DATE, @end DATE;
SELECT @start = '20171215', @end = '20180107';

;WITH n AS 
(
  SELECT TOP (DATEDIFF(DAY, @start, @end) + 1) 
   n = ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_objects
)
SELECT DATEADD(DAY, n-1, @start) as Date
into #Days
FROM n;

现在我们有了天数列表,只需将您的列表加入天数列表即可。

select d.date
    , case when b.boo_id is null then 'No Bookings' else 'Booking #' + 
        cast(b.boo_id as varchar(255)) +
        ' In ' + case when b.boo_id is null then ''
            when d.date = b.BOO_DateCI then 'Checking In'
            when d.date = b.BOO_DateCO Then 'Checking Out'
            else 'In House' end as BookingStatus
from #Days d
  left outer join ___Bookings b
    on d.date between b.BOO_DateCI and b.BOO_DateCO

如果有一天没有来宾,我们使用左外连接,并且由于我们使用左,我们必须优雅地考虑空值,这是 isnull 和 case 语句的工作。剩下的就是一些演绎推理,date_CI 可能是签入,date_CO 可能是签出。希望对您有所帮助!

【讨论】:

  • 你好。谢谢你的帮助。您的答案中的第一个代码是否应该运行到 phpMySql 中?我正在使用 PHP。
  • 添加 $Sql = 然后加上引号?抱歉,我不太擅长 PHP,但要考虑的一件事是 php 可能一次只执行一项事务,因此您可能必须将它们组合成一个语句。
  • @Randall - 第二个查询应该有效。第一个需要用 MySQL 重写。看看这里:stackoverflow.com/questions/10132024/…
  • 天数列表不是必需的。
  • @Strawberry,我也这么认为,但我怎么能这样呢?感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
相关资源
最近更新 更多