Help in logic to not overlap a band of schedules already exists at the base

Asked

Viewed 185 times

0

Good morning. As suggested by a community member, in the post that started this, I come to ask for collaboration in a logic. I have a table that contains the fields start time and hora_termino. I need a routine that makes it impossible for the user to enter a time zone that overlaps existing ones, regardless of the day. Any time slot between 24 hours can therefore be inserted. Imagine that the table is filled with these values:

   inicio        termino
1) '07:00:00' - '09:00:00'
2) '09:00:00' - '11:30:00'
3) '12:00:00' - '15:35:00'
4) '22:35:00' - '01:49:00'

The set of parameters below could not be inserted as they overlap the existing schedules.

Não poderia ser inserido:
   inicio        termino
1) '07:00:01' - '08:00:00'
2) '10:00:00' - '11:32:00'
3) '06:00:00' - '23:00:00'

In short, a time cannot overlap an existing one.

I would like to create an SQL statement or a Stored Procedure that returns true or false, saying whether or not to insert the time range sent by the start and end parameters. The times below could be entered:

   inicio        termino
1) '06:00:00' - '06:30:00'
2) '11:30:00' - '12:00:00'
3) '15:35:00' - '16:12:00'

An important observation is that a time slot can be inserted starting at the same time that another already registered one ends. It can stay this way:

   inicio        termino
1) '06:00:00' - '12:00:00'
2) '12:00:00' - '18:00:00'
3) '18:00:00' - '00:00:00'
4) '00:00:00' - '06:00:00'

Thanks in advance for the support.

1 answer

3


You can check each time using the clause BETWEEN from the database. To correctly handle dates when the start time is lower than the end, we must add a period.

Take an example:

SELECT
COUNT(*) AS qtd

FROM tempo
WHERE TIME_TO_SEC('23:52:00') BETWEEN 
TIME_TO_SEC(inicio) AND 

(TIME_TO_SEC(termino) + IF(inicio > termino, 24 * 60 * 60, 0))

The secret of the query is to convert the schedules to seconds with the function TIME_TO_SEC. The treatment of shorter hours is done by adding one more day (in seconds) to the total time.

To correctly check the value, we must have a query for each of the parameters informed, and the final count must return a zeroed value. A complete and functional example of overlap:

SET @inicio = '06:00:00';
SET @termino = '10:00:00';

SET @inicioSegundos = TIME_TO_SEC(@inicio);
SET @terminoSegundos = TIME_TO_SEC(@termino);

/* A clausula BETWEEN inclui o valor do inicio, portanto podemos adicionar 1 segundo para evitar este problema */
SET @inicioSegundos = @inicioSegundos + 1;

SET @umDia = 24 * 60 * 60;

SELECT
COUNT(*) qtd
FROM tempo
WHERE 
  (@inicioSegundos  BETWEEN TIME_TO_SEC(inicio) AND (TIME_TO_SEC(termino) + IF(inicio > termino, @umDia, 0)))
OR
  (@terminoSegundos BETWEEN TIME_TO_SEC(inicio) AND (TIME_TO_SEC(termino) + IF(inicio > termino, @umDia, 0)))
OR
  (TIME_TO_SEC(inicio)  BETWEEN @inicioSegundos AND (@terminoSegundos + IF(@inicioSegundos > @terminoSegundos, @umDia, 0)))
OR
  (TIME_TO_SEC(termino) BETWEEN @inicioSegundos AND (@terminoSegundos + IF(@inicioSegundos > @terminoSegundos, @umDia, 0)))
OR
  (TIME_TO_SEC(inicio) = TIME_TO_SEC(termino))

For this example I am considering the following data structure:

CREATE TABLE tempo(
  inicio TIME NOT NULL,
  termino TIME NOT NULL
);

insert into tempo(inicio, termino)
VALUES
('07:00:00' , '09:00:00'),
('11:00:00' , '11:30:00'),
('12:00:00' , '15:35:00'),
('23:50:00' , '03:30:00')

Edit 22/03/2017

I added a special treatment in case there is a full day schedule, for example, start = 10:00:00 and finish = 10:00:00.

I also added a treatment to ignore the opening hours in the enclosure BETWEEN.

  • Only have the problem of turning the day within the interval, for example, from 23:00 to 01:00:00. If check the time 23:30:00, the query would bring qtd equal to 0.

  • Just that. The problem is when the day turns. Oh that’s the pineapple!

  • jlHertel, but remembering that are 2 parameters that must be checked with the fields start and end of the table. Finding out if a time is between start and finish was quiet, thanks to the help of @Andersoncarloswoss. But and when are 2 input parameters?

  • Just make the same logic for the final time and join the clauses. See what was done in the answer and try there.

  • Right. This solves the problem of knowing if the search is entering beginning and end, be it the search of the beginning parameter or the end parameter. The question now is whether there is a value that overlap... make a test.. keep only the value <pre>'07:00:00' - '09:00:00'</pre> in the table and imagine that if you insert <pre>'06:00:00' - '10:00:00'</pre>... according to this Select, this insertion will be allowed!

  • @jlHertel, what a fantastic script you made. I did some tests but he still lets me add these values: 00:00 to 00:00, 00:01 to 00:01, 00:02 to 00:02. Where do you have to change it so it doesn’t make it possible? Just to point out (this I was going to try to change here), that an initial time may be the same as the final time, that is, there may be 10:00 to 11:00, 11:00 to 15:37, 15:37 to 22:49.. that is, suddenly the user can define that this period is 24h... from 0h to 0h. Will complicates a lot?

  • Oh yes... I’m new here, and I still don’t quite understand how it works. The textarea placeholder says "Use comments to ask for more information or suggest improvements." That is why I referred here to the improvement in terms of being able to enter overlapping schedules and the detail that a new record may have the initial time being the same final time as an existing record. Is it better to create a new question?

  • @jlHertel, I edited the question. I now understand. It’s nice to keep a leaner page with a question and an objective answer! I thank you already.

  • @LECO, I HAVE ADDED TWO MORE TREATMENTS FOR CASES OF HAVING AN HOUR THAT TAKES THE WHOLE DAY AND ALSO FOR EQUAL INITIAL AND FINAL HOURS. Note: I will delete some of the comments of this reply, not to get so polluted for future readers.

  • @jlHertel, I did the tests, and the only thing that 'gave trouble' is the following, for example, if you add '09:00:00' - '10:00:00', '10:00:00' - '11:00:00', '11:00:00' - '12:00:00', it goes smoothly. However, if you add '08:00:00' - '09:00:00' already having '09:00:00' - '10:00:00' it does not allow. It seems that he allows it when the time is longer than the time has... I can understand?

  • @Leco, the idea is exactly the same as the initial treatment. What happens if you subtract 1 second from the final time? In theory this would solve your problem.

  • @jlHertel, I get it. It was right. Had spent days thinking about this routine. You helped me too much. I do not know how to thank. I learned a lot from you and your 'select cabuloso'. Thank you very much for everything and a strong hug.

Show 7 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.