小时数的复杂计算

Complex calculation of the hours amount

我有一个 Pythonic 系统,可以将学生缺勤数据存储在 SQLite 数据库中。每行包括缺勤的开始和结束时间,以自 1970 年 1 月 1 日以来的秒数表示。我被要求添加一个功能来限制每周缺勤的小时数。

提取小时数听起来很容易,使用这样的语句:

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

问题是限制只能是定义为 "mandatory presence." 的小时数 例如,如果用户将小时数 8:00 到 17:00 定义为 "mandatory presence," 从星期天14:00开始到星期一同一时间结束的缺席,在上面的代码中将计算为24小时,而实际上只有9小时。

"Mandatory presence" 在数据库中定义为两个数值参数:"morning" 和 "evening"(始终为一个小时)。有没有办法在考虑这两个数字的情况下进行上述计算? 如果不能在sql中完成,我很想听听如何selectsql中的数据,然后在python中进行计算。

我相信以下内容可能会如您所愿:-

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
;

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;

非常感谢您的帮助!