如何获得从开始日期到结束日期的全天数和半天数

How does one get number of full days and half days from a start and end date

背景

我一直在处理一些需要多天轮班的报告视图,并且应该根据数据进行一些计算,但我有点卡在这里。 一个典型的班次是 3 个日历日,通常是 1 个半天和两个全天,或者是一个由 2 个半天(结束和开始)和 5 个全天组成的整周。

规格

对于什么是全天和半天,我有以下规范。这些规则基于法规,无法更改。

我在考虑每全天和半天一行,或者使用 half_days 和 full_days 的聚合行作为两个单独的列,在视图中连接它是理想的我的其他看法。

简化模型

我简化了数据模型以删除不必要的列。

create table if not exists [trip]
(
    trip_id    integer
        constraint trip_pk
            primary key,
    started_at text default (datetime('now')),
    end_at     text default (datetime('now'))
);

而且我对应该如何设计这个查询有点困惑。简单的时间增量不起作用。

带有示例数据和答案的 SQLFiddle:http://sqlfiddle.com/#!5/de7551/2

您可以使用 CTE 来解决此问题,该 CTE 计算天数跨度(轮班跨度的天数)。由于半天总是 1、2 或 0(仅出现在结束和开始时),我们实际上不需要单独考虑每一天。

您可以使用 julianday 来获取日期的数字,但是 julian days 从中午开始,因此您需要减去 0.5 以获得计算的“实际”日期。如果结束时间晚于每一天的开始时间,则将结束日设置为底数以避免跨度过长,并将结果四舍五入以将部分天数作为跨度天数。

此时我们可以通过检查结束和开始来计算半天数。要获得完整的天数,我们只需从结果中减去半天。

with trip_spans as (
select
    ceil(julianday(end_at)-0.5 - floor(julianday(started_at)-0.5)) day_span
    , t.*
    , (
        iif(time(started_at) > time('12:00'), 1, 0)
        +
        iif(time(end_at) <= time('19:00'), 1, 0)
     ) half_days
    from trip t
)
select
    trip_spans.*
    , day_span-half_days full_days
from trip_spans