SQL-запрос о встречах

0

Предположим, что у нас есть эта таблица.

CREATE TABLE `appointments` (
  `idappointments` int(11) NOT NULL AUTO_INCREMENT,
  `timeStart` time DEFAULT NULL,
  `timeEnd` time DEFAULT NULL,
  PRIMARY KEY (`idappointments`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8$$

предположение

Предположим, что диапазон между timeStart и timeEnd can not существует снова... Я имею в виду, что если мы пересекаем все диапазоны в таблице, результат будет ПУСТОЙ, 0, null. Назначение can not cooexist с другим.

Итак, что я хочу сделать, это предложение времени, если желаемое время занято... Предложение до и предложение после желаемого времени....

Так мне было интересно, а не писать код, чтобы сделать это, если я могу написать SQL-запрос, чтобы найти ближайшие пустые диапазоны......

Ex.. timeStart - NEAREST_TO_TIMESTART_TIMEEND > '10 минут ', а 10 минут - продолжительность

  • 1
    К вашему сведению, в SQL NULL и 0 разные :)
  • 0
    Если вы только фиксируете время, как вы узнаете, в какой день назначено назначение?
Показать ещё 1 комментарий
Теги:

1 ответ

2
Лучший ответ

MySQL не имеет рекурсивной функциональности, поэтому вам остается использовать трюк таблицы NUMBERS -

  • Создайте таблицу, содержащую только инкрементные числа - легко сделать с помощью auto_increment:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  • Заполните таблицу, используя:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ... для количества значений, которые вам нужны.

  • Используйте DATE_ADD, чтобы создать список дат, увеличивая дни на основе значения NUMBERS.id. Замените "2010-01-01" и "2010-01-02" на соответствующие даты начала и окончания (но используйте тот же формат, YYYY-MM-DD HH: MM: SS) -

    SELECT x.dt
      FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
    
  • LEFT JOIN на таблицу данных, основанную на части datetime.

Это покажет вам первый доступный слот:

       SELECT x.dt
      FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
    LEFT JOIN APPOINTMENTS a ON x.dt BETWEEN a.timestart AND a.timeend
        WHERE a.idappoinment IS NULL
          AND x.dt > @your_minimum_datetime
     ORDER BY x.dt
        LIMIT 1

Это покажет вам доступность на весь день:

       SELECT x.dt,
              CASE 
                WHEN a.idappoinment IS NULL THEN 'available'
                ELSE 'booked'
              END AS isbooked 
      FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
    LEFT JOIN APPOINTMENTS a ON x.dt BETWEEN a.timestart AND a.timeend
     ORDER BY x.dt

Почему числа, а не даты?

Простые даты могут быть сгенерированы на основе числа, как в приведенном выше примере. Это также означает использование одной таблицы, например, для каждого типа данных.

  • 0
    здорово ... Но не вызовет ли это ограничение продолжительности?
  • 0
    @Parhs: вы можете изменить создание минутного значения в соответствии с вашими потребностями - его можно изменить на секунды, если вам нужна такая большая точность.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню