简体   繁体   中英

SQL - Split open & Close time Into intervals of 30 minutes

Purpose: I work in Hospitality Industry. I want to understand at what time the Restaurant is full and what time it is less busy. I have the opening and closing times, I want to split it 30 minute interval period.

I would really appreciate if you could ease help me.

Thanking you in advance

Table

Check# Open CloseTime
25484   17:34   18:06
25488   18:04   21:22

Output

Check# Open Close   Duration
25484   17:34   18:00   0:25
25484   18:00   18:30   0:30
25488   18:08   18:30   0:21
25488   18:30   19:00   0:30
25488   19:00   19:30   0:30
25488   19:30   20:00   0:30
25488   20:00   20:30   0:30
25488   20:30   21:00   0:30
25488   21:00   21:30   0:30

I am new to SQL. I am good at Excel, but due to its limitations i want to use SQL. I just know the basics in SQL. I have tried on the google, but could not find solution to it. All i can see use of Date Keywords, but not the Field name in the code, hence i am unable to use them.

Could you try this, it works in MySQL 8.0:

WITH RECURSIVE times AS (
  SELECT time '0:00' AS `Open`, time '0:30' as `Close`
   UNION ALL
  SELECT addtime(`Open`, '0:30'), addtime(`Close`, '0:30')
    FROM times
   WHERE `Open` < time '23:30'
)
SELECT c.`Check`,
       greatest(t.`Open`, c.`Open`) `Open`,
       least(t.`Close`, c.`CloseTime`) `Close`,
       timediff(least(t.`Close`, c.`CloseTime`), greatest(t.`Open`, c.`Open`)) `Duration`
  FROM times t
  JOIN checks c ON (c.`Open` < t.`Close` AND c.`CloseTime` > t.`Open`);

| Check | Open     | Close    | Duration |
| ----- | -------- | -------- | -------- |
| 25484 | 17:34:00 | 18:00:00 | 00:26:00 |
| 25484 | 18:00:00 | 18:06:00 | 00:06:00 |
| 25488 | 18:04:00 | 18:30:00 | 00:26:00 |
| 25488 | 18:30:00 | 19:00:00 | 00:30:00 |
| 25488 | 19:00:00 | 19:30:00 | 00:30:00 |
| 25488 | 19:30:00 | 20:00:00 | 00:30:00 |
| 25488 | 20:00:00 | 20:30:00 | 00:30:00 |
| 25488 | 20:30:00 | 21:00:00 | 00:30:00 |
| 25488 | 21:00:00 | 21:22:00 | 00:22:00 |

-> Fiddle

This works for SQL Server 2019:

WITH times([Open], [Close]) AS (
  SELECT cast({t'00:00:00'} as time) as "Open",
         cast({t'00:30:00'} as time) as "Close"
   UNION ALL
  SELECT dateadd(minute, 30, [Open]), dateadd(minute, 30, [Close])
    FROM times
   WHERE [Open] < cast({t'23:30:00'} as time)
)
SELECT c.[Check],
       iif(t.[Open] > c.[Open], t.[Open], c.[Open]) as [Open],
       iif(t.[Close] < c.[CloseTime], t.[Close], c.[CloseTime]) as [Close],
       datediff(minute,
                iif(t.[Open] > c.[Open], t.[Open], c.[Open]),
                iif(t.[Close] < c.[CloseTime], t.[Close], c.[CloseTime])) Duration
  FROM times t
  JOIN checks c ON (c.[Open] < t.[Close] AND c.[CloseTime] > t.[Open]);

Check  | Open              | Close             | Duration
25484  | 17:34:00.0000000  | 18:00:00.0000000  | 26
25484  | 18:00:00.0000000  | 18:06:00.0000000  | 6
25488  | 18:04:00.0000000  | 18:30:00.0000000  | 26
25488  | 18:30:00.0000000  | 19:00:00.0000000  | 30
25488  | 19:00:00.0000000  | 19:30:00.0000000  | 30
25488  | 19:30:00.0000000  | 20:00:00.0000000  | 30
25488  | 20:00:00.0000000  | 20:30:00.0000000  | 30
25488  | 20:30:00.0000000  | 21:00:00.0000000  | 30
25488  | 21:00:00.0000000  | 21:22:00.0000000  | 22

-> Fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM