Комплексный подсчет количества часов - PullRequest
0 голосов
/ 21 июня 2019

У меня есть система Pythonic, которая хранит данные об отсутствии учащихся в базе данных SQLite. Каждая строка содержит время начала и окончания отсутствия, представленное количеством секунд с 01 января 1970 года. Меня попросили добавить функцию, которая ограничивает количество часов отсутствия в неделю.

Звучит легко вывести количество часов, используя такое выражение:

SELECT (sum(ending-starting)/3600) 
FROM requests
WHERE student_id = {x}
AND starting BETWEEN {y} AND ({y}+604800)
AND approved = 1 

Проблема в том, что пределом должны быть только часы, определенные как «обязательное присутствие». Например, если пользователь определил часы с 8:00 до 17:00 как «обязательное присутствие», то отсутствие, которое начинается в воскресенье в 14:00 и заканчивается в понедельник в одно и то же время, будет рассчитываться в приведенном выше коде 24 часа, а на практике это всего 9 часов.

«Обязательное присутствие» определяется в базе данных как два числовых параметра: «утро» и «вечер» (всегда круглый час). Есть ли способ сделать расчет выше с учетом этих двух чисел? Если это не может быть сделано в SQL, я хотел бы услышать, как выбрать данные в SQL и затем выполнить вычисления в Python.

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Ответ MikeT не совсем работает, но он, безусловно, помог мне достичь желаемого результата. Вот идеальное утверждение:

SELECT
(
    sum((
        (ending - starting)
        -(
            CASE WHEN starting < strftime('%s',date(starting,'unixepoch')||printf(' %02d:00', morning))
            THEN strftime('%s',date(starting,'unixepoch')||printf(' %02d:00', morning)) - starting 
            ELSE 0 
            END
            +
            CASE WHEN ending > strftime('%s',date(ending,'unixepoch')||printf(' %02d:00', evening))
            THEN ending - strftime('%s',date(ending,'unixepoch')||printf(' %02d:00', evening))
            ELSE 0 
            END
        )
    ) /3600.0
    -(
      (24-evening+morning)
      *
      (round(julianday(ending, 'unixepoch'))-round(julianday(starting, 'unixepoch')))
    )
)) AS ha
FROM requests
INNER JOIN students ON requests.student_id = students.ID
INNER JOIN institutes ON students.inst_id = institutes.ID
WHERE student_id = {x}
AND starting BETWEEN {y} AND ({y}+604800)
AND approved = 1;

Большое спасибо за помощь!

0 голосов
/ 22 июня 2019

Я полагаю, что следующее может делать то, что вы хотите: -

SELECT
    (
        sum((
            (ending - starting)
            -(
                CASE WHEN starting < strftime('%s',date(starting,'unixepoch')||' 08:00') 
                THEN strftime('%s',date(starting,'unixepoch')||' 08:00') - starting 
                ELSE 0 
                END
                +
                CASE WHEN ending > strftime('%s',date(starting,'unixepoch')||' 17:00') 
                THEN ending - strftime('%s',date(starting,'unixepoch')||' 17:00') 
                ELSE 0 
                END
            )
        ) /3600)
) AS ha, *
FROM requests
WHERE student_id = {x}
AND starting BETWEEN {y} AND ({y}+604800)
AND approved = 1
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...