如何获得从开始日期到结束日期的全天数和半天数
How does one get number of full days and half days from a start and end date
背景
我一直在处理一些需要多天轮班的报告视图,并且应该根据数据进行一些计算,但我有点卡在这里。
一个典型的班次是 3 个日历日,通常是 1 个半天和两个全天,或者是一个由 2 个半天(结束和开始)和 5 个全天组成的整周。
规格
对于什么是全天和半天,我有以下规范。这些规则基于法规,无法更改。
- 2个半天!= 1个全天,2个半天更“有价值”
- 给定
started_at
iso datetime 和 end_at
iso datetime
- 我想得到两个数字,full_days和half_days
- 半天是
- 范围的 开始 的一天 在 12.00
或之后开始
- 范围 结束 的一天,在 19.00
之前结束
- 一整天是
- 范围内的一天(传统 24 小时)
- 范围的 开始 的一天 在 12.00
之前
- 范围结束 的一天 在 19.00
或之后结束
我在考虑每全天和半天一行,或者使用 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
背景
我一直在处理一些需要多天轮班的报告视图,并且应该根据数据进行一些计算,但我有点卡在这里。 一个典型的班次是 3 个日历日,通常是 1 个半天和两个全天,或者是一个由 2 个半天(结束和开始)和 5 个全天组成的整周。
规格
对于什么是全天和半天,我有以下规范。这些规则基于法规,无法更改。
- 2个半天!= 1个全天,2个半天更“有价值”
- 给定
started_at
iso datetime 和end_at
iso datetime - 我想得到两个数字,full_days和half_days
- 半天是
- 范围的 开始 的一天 在 12.00 或之后开始
- 范围 结束 的一天,在 19.00 之前结束
- 一整天是
- 范围内的一天(传统 24 小时)
- 范围的 开始 的一天 在 12.00 之前
- 范围结束 的一天 在 19.00 或之后结束
我在考虑每全天和半天一行,或者使用 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