С помощью отладочного подзапроса, который представлен вместо таблицы t, можно увидеть особенности нумерации и определения отрезка на границах интервала и всего периода.
(select STR_TO_DATE('01.06.2018 08:50:00', '%d.%m.%Y %H:%i:%s') event_date union all -- до дневного периода
select STR_TO_DATE('01.06.2018 08:59:59', '%d.%m.%Y %H:%i:%s') event_date union all -- за секунду до начала дневного периода
select STR_TO_DATE('01.06.2018 09:00:00', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно на начале дневного периода первого интервала
select STR_TO_DATE('01.06.2018 09:00:01', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно после одной секунды в первом интервале дневного периода
select STR_TO_DATE('01.06.2018 09:14:59', '%d.%m.%Y %H:%i:%s') event_date union all -- за секунду до окончания первого интервала
select STR_TO_DATE('01.06.2018 09:15:00', '%d.%m.%Y %H:%i:%s') event_date union all -- начало второго интервала
select STR_TO_DATE('01.06.2018 09:15:01', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно после первой секунды второго интервала
select STR_TO_DATE('01.06.2018 17:59:59', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно за секунду до окончания дневного периода
select STR_TO_DATE('01.06.2018 18:00:00', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно на границе дневного периода
select STR_TO_DATE('01.06.2018 18:00:01', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно секунда после дневного периода
select STR_TO_DATE('01.06.2018 18:10:00', '%d.%m.%Y %H:%i:%s') event_date) t
select @time_counter := @time_counter + 1 as number, -- номер интервала
SEC_TO_TIME(inter2.width) as width, -- ширина интервала
SEC_TO_TIME(@time_step) as begin, -- начало интервала
SEC_TO_TIME(@time_step := @time_step + inter2.width) as end -- конец интервала
from any_big_table, -- любая таблица, у которой в любую погоду всегда найдется over9000 строк
(
select inter.*, -- передаем константы выше как они есть
@time_step := inter.begin, -- счетчик по времени
@time_counter := 0 -- счетчик по порядку
from (
select TIME_TO_SEC('09:00:00') as begin, -- начало дневного периода
TIME_TO_SEC('18:00:00') as end, -- окончание дневного периода
TIME_TO_SEC('00:15:00') as width -- ширина интервала
) inter -- константно-параметрический подзапрос
) inter2 -- общий параметрический подзапрос, несет на себе функцию инициализации переменных-счетчиков @time_step и @time_counter
where @time_step >= inter2.begin -- нижнее ограничение выборки
and @time_step + inter2.width <= inter2.end -- верхнее ограничение выборки
private List<Lesson> Lessons = new List<Lesson>();
private Lesson lesson_Add(string name, string path, string description)
{
Lesson lesson = new Lesson(name, path, description);
Lessons.Add(Lesson); // создали тему и положили ее в список, который будет доступен в классе формы, хорошо бы его использовать через свой класс помимо того, что есть класс для элемента списка.
ToolStripItem menuitem = themesToolStripMenuItem.DropDownItems.Add(lesson.LessonDescription);
menuitem.Name = lesson.LessonName;
menuitem.Tag = Lessons.Count() - 1; // закладываем информацию об индексе из списке тем в элемент меню, чтобы потом достать ее при обращении к sender
menuitem.Click += new EventHandler(lesson_Click);
return lesson;
}
var menu_item = (ToolStripMenuItem) sender; // из объекта sender получаем элемент события, его нужно привести к соответствующему типу объекта интерфейса
var less_index = Convert.ToInt32(menu_item.Tag); // из тега достаем информацию, как нам обратиться к элементу, с которым связано отображение, в данном случае тут используем индекс в списке элементов тем, но можно положить любую произвольную инфу.
var less_path = Lessons[less_index].LessonPath; // обращаемся к списку тем и достаем нужное свойство
textBox1.Text = less_path; // выводим свойство
SELECT t.event_date,
case
when TIME_TO_SEC(t.event_date) >= inter.begin AND TIME_TO_SEC(t.event_date) < inter.end -- типичный случай, определяем номер интервала
then floor((TIME_TO_SEC(t.event_date) - inter.begin) / inter.width) + 1
when TIME_TO_SEC(t.event_date) = inter.end -- особый случай, определяем правильный номер интервала ровно на окончании дневного периода
then floor((inter.end - inter.begin) / inter.width)
when TIME_TO_SEC(t.event_date) < inter.begin -- маркируем номер интервала до начала дневного периода
then -1
when TIME_TO_SEC(t.event_date) > inter.end -- маркируем номер интервала после окончания дневного периода
then -2
else null -- экстраситуация, если when-then охватывают все условия, то сюда никогда не попадем
end as full_interval_number,
case
when TIME_TO_SEC(t.event_date) >= inter.begin AND TIME_TO_SEC(t.event_date) < inter.end -- типичный случай, определяем время начала интервала
then SEC_TO_TIME(floor((TIME_TO_SEC(t.event_date) - inter.begin) / inter.width) * inter.width + inter.begin)
when TIME_TO_SEC(t.event_date) = inter.end -- особый случай, определяем правильное время начала интервала ровно на окончании дневного периода
then SEC_TO_TIME(floor((TIME_TO_SEC(t.event_date) - inter.begin - 1) / inter.width) * inter.width + inter.begin)
when TIME_TO_SEC(t.event_date) < inter.begin -- если за пределами дневного периода, то время окончания за-null-яем
OR TIME_TO_SEC(t.event_date) > inter.end
then null
else null -- экстраситуация, если when-then охватывают все условия, то сюда никогда не попадем
end as full_interval_begin,
case
when TIME_TO_SEC(t.event_date) >= inter.begin AND TIME_TO_SEC(t.event_date) < inter.end -- типичный случай, определяем время окончания интервала
then SEC_TO_TIME(ceil((TIME_TO_SEC(t.event_date) - inter.begin + 1) / inter.width) * inter.width + inter.begin)
when TIME_TO_SEC(t.event_date) = inter.end -- особый случай, определяем правильное время окончания интервала ровно на окончании дневного периода
then SEC_TO_TIME(ceil((TIME_TO_SEC(t.event_date) - inter.begin - 1) / inter.width) * inter.width + inter.begin)
when TIME_TO_SEC(t.event_date) < inter.begin -- если за пределами дневного периода, то время окончания за-null-яем
OR TIME_TO_SEC(t.event_date) > inter.end
then null
else null -- экстраситуация, если when-then охватывают все условия, то сюда никогда не попадем
end as full_interval_end
FROM (select STR_TO_DATE('01.06.2018 08:50:00', '%d.%m.%Y %H:%i:%s') event_date union all -- до дневного периода
select STR_TO_DATE('01.06.2018 08:59:59', '%d.%m.%Y %H:%i:%s') event_date union all -- за секунду до начала дневного периода
select STR_TO_DATE('01.06.2018 09:00:00', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно на начале дневного периода первого интервала
select STR_TO_DATE('01.06.2018 09:00:01', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно после одной секунды в первом интервале дневного периода
select STR_TO_DATE('01.06.2018 09:14:59', '%d.%m.%Y %H:%i:%s') event_date union all -- за секунду до окончания первого интервала
select STR_TO_DATE('01.06.2018 09:15:00', '%d.%m.%Y %H:%i:%s') event_date union all -- начало второго интервала
select STR_TO_DATE('01.06.2018 09:15:01', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно после первой секунды второго интервала
select STR_TO_DATE('01.06.2018 17:59:59', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно за секунду до окончания дневного периода
select STR_TO_DATE('01.06.2018 18:00:00', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно на границе дневного периода
select STR_TO_DATE('01.06.2018 18:00:01', '%d.%m.%Y %H:%i:%s') event_date union all -- ровно секунда после дневного периода
select STR_TO_DATE('01.06.2018 18:10:00', '%d.%m.%Y %H:%i:%s') event_date) t, -- после дневного периода
(select TIME_TO_SEC('09:00:00') as begin, -- начало дневного периода
TIME_TO_SEC('18:00:00') as end, -- окончание дневного периода
TIME_TO_SEC('00:15:00') as width -- ширина интервала
) inter
Чем обусловлено такое ограничение?