Упорядочить запрос для перекрывающихся событий

#javascript #mysql #node.js #datetime #sequelize.js

#javascript #mysql #node.js #дата и время #sequelize.js

Вопрос:

Я пытаюсь выполнить запрос findAll () с помощью Sequelize, который выполняет следующее. Я хочу иметь возможность вводить идентификатор пользователя и выполнять поиск в таблице событий, чтобы определить, перекрываются ли события других пользователей с любым из событий выбранного пользователя. Я хочу убедиться, что события перекрываются как минимум на 30 минут.

 Events table
id     start                  end                    createdByUser
1      2020-08-17 05:00:00    2020-08-17 08:00:00    1
2      2020-08-17 06:00:00    2020-08-17 11:00:00    2
3      2020-08-17 07:00:00    2020-08-17 11:00:00    3
4      2020-08-18 12:00:00    2020-08-18 13:00:00    1
5      2020-08-18 12:50:00    2020-08-18 14:00:00    2
6      2020-08-18 09:00:00    2020-08-18 12:10:00    3
7      2020-08-18 12:00:00    2020-08-18 12:45:00    4
8      2020-08-18 15:00:00    2020-08-18 18:00:00    2
  

Пример: я хочу иметь возможность сказать «посмотрите на все события пользователя 1. Посмотрите, не перекрываются ли события других пользователей с каким-либо из событий пользователя 1 хотя бы на 30 минут.» Если бы возвращаемые данные запроса могли каким-то образом указывать, с каким из событий пользователя 1 они перекрываются, это было бы еще лучше! Что-то вроде следующего:

 {id: 2,
 start: 2020-08-17 06:00:00,
 end: 2020-08-17 11:00:00,
 createdByUser: 2,
 overlapWithEventID: 1
},
{id: 3,
 start: 2020-08-17 07:00:00,
 end: 2020-08-17 11:00:00,
 createdByUser: 3,
 overlapWithEventID: 1
},
{id: 7,
 start: 2020-08-18 12:00:00,
 end: 2020-08-18 12:45:00,
 createdByUser: 4,
 overlapWithEventID: 4
}
  

Заранее спасибо за помощь! Это более сложный запрос, чем я привык делать.

Ответ №1:

 SELECT t2.*, t1.id overlapWithEventID
FROM events t1
JOIN events t2
WHERE t1.createdByUser = 1
  AND t2.createdByUser != 1
  AND TIMESTAMPDIFF(MINUTE, GREATEST(t1.start, t2.start), LEAST(t1.`end`, t2.`end`)) >= 30;
  

скрипка

Настройте на СУБД, которую вы используете.

Комментарии:

1. Спасибо за вашу помощь здесь. Это определенно помогает мне сориентироваться в том, как построить этот запрос. Я обновлю, если смогу успешно перевести запрос в Sequelize.

2. Акина, я нашел способ вызвать необработанную команду MySQL в Sequelize. Ему нужен второй аргумент, чтобы предотвратить отправку метаданных результата (из-за чего создается впечатление, что результат отправляется дважды). Если вы хотите добавить это к своему ответу, я могу принять его. sequelize.query("SELECT t2.*, t1.id overlapWithEventID FROM events t1 JOIN events t2 WHERE t1.createdByUser = 1 AND t2.createdByUser != 1 AND TIMESTAMPDIFF(MINUTE, GREATEST(t1.start, t2.start), LEAST(t1. конец , t2. end )) >= 30;", {type: Sequelize.QueryTypes.SELECT}).then(function (result) { res.json(result); });

3. @JarrettD5309 Лучше создать самостоятельный ответ с помощью хорошо отформатированного кода, а не «лапши» в комментарии.