Хорошо, я выяснил очень грязное решение, используя множество вложенных операторов CASE
. Он проверяет день недели released
, а затем номер дня недели arrival
и делает расчет, чтобы выяснить, сколько недель прошло. После этого я добавляю 0, 1 или 2 в качестве базового числа выходных дней, которое должно было пройти между этими двумя днями (т.е. с пятницы по понедельник всегда +2 выходных дня, даже если прошло менее недели даты).
Здесь он находится на всякий случай, если кто-либо найдет его полезным. Вполне возможно, самый уродливый SQL, который я когда-либо писал. Если кто-нибудь выяснит лучший способ, пожалуйста, дайте мне знать.
(под редакцией для простоты на основе обратной связи CL в)
SELECT
avg(
julianday(released) - julianday(arrival) -
CASE WHEN julianday(released) = julianday(arrival) THEN 0 ELSE
CASE strftime('%w', released)
WHEN '0' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 1)
END
WHEN '1' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 1)
END
WHEN '2' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 1)
END
WHEN '3' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 1)
END
WHEN '4' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 0)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 1)
END
WHEN '5' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 1)
END
WHEN '6' THEN
CASE strftime('%w', arrival)
WHEN '0' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '1' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '2' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '3' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '4' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '5' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
WHEN '6' THEN ((cast((julianday(released)-julianday(arrival))/7 as int) * 2) + 2)
END
END
END
), avg(julianday(released)-julianday(arrival))
from trucks
(Замечание: при avg(julianday(released)-julianday(arrival))
в конце концов, это только для целей тестирования, чтобы показать, что новое расчетное среднее значение на самом деле меньше, чем прямой среднее значение разница между двумя датами).
Mind = взорван. Это уменьшило мой запрос на 635 строк до 97 строк. (Логика выходного дня повторно используется несколько раз в более крупном запросе.) Спасибо человеку! – penco
В качестве небольшого добавления мне пришлось обернуть 'MAX()' вокруг оператора AVG(), потому что изредка получаю отрицательные числа из-за проблем округления. Таким образом, это закончилось как «MAX (AVG (...), 0)». – penco