Итак, исправляю сам себя.
Чтобы в наш интервал не попали 16 часов, он целиком должен помещаться между двумя ближайшими 16-часовыми отметками на временной прямой. Их можно получить искусственно: первая отметка это наиболее поздние дата-время, когда было 16 часов, но не позже, чем
start, а вторая — ровно на сутки позже. Назовём условно эти отметки
a и
b. Так как
start всегда попадает в
[a, b], вся задача сводится к проверке попадания
end в интервал
[a, b]. При
end < b в интервале
[start, end] не будет ни одной 16-часовой отметки. Теперь вернёмся к исходной задаче. Обращаем условие: при
end >= b в интервал
[start, end] попадёт хотя бы одна отметка в 16 часов.
Теперь постараемся получить
b. Чтобы получить
a, вычтем из
start 16 часов, обнулим временную часть (прыгнув таким образом к началу суток) и прибавим обратно 16 часов. Величину
b получить ещё проще: прибавляем сутки к
a.
И в SQL:
SELECT *
FROM my_table
WHERE
end >= DATE( start - INTERVAL '16:00:00' HOUR_SECOND ) + INTERVAL '16:00:00' HOUR_SECOND + INTERVAL 1 DAY