Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

Finding free blocks of time in mysql and php?

I have a table in mysql like this:

+------------+------------+------------+------------+ 
|     date   |   user_id  | start_hour | end_hour   | 
+------------+------------+------------+------------+ 
| 2010-12-15 |         20 | 08:00:00   | 08:15:00   | 
| 2010-12-15 |         20 | 14:00:00   | 14:30:00   | 
| 2010-12-15 |         20 | 17:00:00   | 17:45:00   | 
+------------+------------+------------+------------+ 

and I try to extract the time range of the time of users I found and example here, but I can't make that work on hours

I tried the query:

 $sql="
SELECT a.end_hour AS 'Available From', Min(b.start_hour) AS 'To' 

FROM ( 
SELECT  0 as date, '08:00:00' as start_hour,'08:00:00' as end_hour 
UNION SELECT date, start_hour, end_hour FROM table
) 

AS a JOIN 
( SELECT  date, start_hour, end_hour  FROM table 
UNION SELECT 0,  '21:00:00' as start_hour, '22:00:00' as end_hour
) AS b ON

a.date=b.date AND  a.user_id=b.user_id AND a.end_hour < b.start_hour WHERE  
a.date='$date'  AND a.user_id='$user_id' GROUP BY a.end_hour 
HAVING a.end_hour < Min(b.start_hour);"; 

I need to create a range since 08:00 to 21:00 with the free blocks between the appointments like this:

free time
08:15:00 to 14:00:00
14:30:00 to 17:00:00
17:45:00 to 21:00:00
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this query

SELECT
  a.id,
  a.start_hour,
  a.end_hour,
  TIMEDIFF(la.start_hour, a.end_hour) as `Free Time`
FROM appointment as a
  LEFT JOIN(SELECT * FROM appointment LIMIT 1,18446744073709551615) AS la
    ON la.id = a.id + 1
  LEFT JOIN (SELECT * FROM appointment) AS ra ON a.id = ra.id

This will show these results

+---------------------------------------------+
| id | start_hour BY | end_hour   | Free Time |
|----+---------------|------------------------|
|  1 |   08:00:00    |  08:15:00  | 05:45:00  |
|  2 |   14:00:00    |  14:30:00  | 02:30:00  |
|  3 |   17:00:00    |  17:45:00  | 03:15:00  |
|  4 |   21:00:00    |  21:00:00  | (NULL)    |
+--------------------+------------------------+ 

Also you must have the 21:00:00 in the table or you wont be able to get the last time difference. i entered 21:00:00 as start and end date in the table.

EDITED

This is modified query

SELECT
  a.id,
  a.end_hour AS `Free time Start`,
  IFNULL(la.start_hour,a.end_hour) AS `Free Time End`,
  IFNULL(TIMEDIFF(la.start_hour, a.end_hour),'00:00:00') AS `Total Free Time`
FROM appointment AS a
  LEFT JOIN (SELECT * FROM appointment LIMIT 1,18446744073709551615) AS la
    ON la.id = (SELECT MIN(id) FROM appointment where id > a.id LIMIT 1)      

And the result is

+--------------------------------------------------------+
| id | Free time Start | Free Time End | Total Free Time |
|----+-----------------|---------------------------------|
|  1 |   08:15:00      | 14:00:00      |    05:45:00     |
|  2 |   14:30:00      | 17:00:00      |    02:30:00     |
|  3 |   17:45:00      | 21:00:00      |    03:15:00     |
|  4 |   21:00:00      | 21:00:00      |    00:00:00     |
+----------------------+---------------------------------+  

The points to learn from this query are

  1. Timediff function usage. timediff('end time','start time')
  2. Joining with upper number
  3. Avoid first record in join with a long offset and limit starting from 1 instead of zero
  4. IFNULL usage ifnull('if here comes null','select this then')

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...