简体   繁体   English

在没有扩展功能的SQLite中从SQL中获取日期范围内的工作日数

[英]get number of working days from date range in SQL for sqlite without extension functions

I have a table that contains the columns start and end , which contain the start and end date of a date range. 我有一个表,其中包含列startend ,其中包含日期范围的开始和结束日期。 I want to select the number of working days (number of days excluding saturday and sunday) using pure sqlite3 functionality from each time range. 我想使用每个时间范围内的纯sqlite3功能选择工作日数(不包括周六和周日的天数)。 Is there any way to do this? 有什么办法吗?

I checked the several answers for this problem, but many seem to use functions like DATEDIFF which aren't available in sqlite. 我检查了几个解决此问题的答案,但是许多答案似乎使用了DATEDIFF函数,而这些函数在sqlite中不可用。

Example: Start date '2015-09-19' and end date '2015-09-22' should result in two working days. 示例:开始日期为“ 2015-09-19”和结束日期为“ 2015-09-22”应该需要两个工作日。

If you had a table like this, your job would be easy. 如果您有这样的桌子,您的工作将很容易。

-- I'm going to drop this table later.
create table calendar (
  cal_date date primary key
);

insert into calendar values ('2015-09-18');
insert into calendar values ('2015-09-19');
insert into calendar values ('2015-09-20');
insert into calendar values ('2015-09-21');
insert into calendar values ('2015-09-22');
insert into calendar values ('2015-09-23');

-- Weekdays
select cal_date, strftime('%w', cal_date) day_of_week
from calendar
where day_of_week between 1 and 5;
cal_date    day_of_week
----------  -----------
2015-09-18  5          
2015-09-21  1          
2015-09-22  2          
2015-09-23  3
-- Weekdays between two dates
select cal_date, strftime('%w', cal_date) day_of_week
from calendar
where day_of_week between 1 and 5
  and cal_date between '2015-09-19' and '2015-09-22';
cal_date    day_of_week
----------  -----------
2015-09-21  1          
2015-09-22  2
-- Count them
select count(*) num_days
from (select cal_date, strftime('%w', cal_date) day_of_week
      from calendar
      where day_of_week between 1 and 5
        and cal_date between '2015-09-19' and '2015-09-22') x;
num_days  
----------
2

So let's manufacture a table like that from start and end dates. 因此,让我们从开始日期和结束日期开始制作一张这样的表格。 To do that, we need a table of integers. 为此,我们需要一个整数表。

create table integers (
  n integer primary key
);

insert into integers values (0);
insert into integers values (1);
insert into integers values (2);
insert into integers values (3);
insert into integers values (4);
insert into integers values (5);

The number of rows you insert is important. 您插入的行数很重要。 The lowest start date plus the largest integer usually needs to return a result later than the latest end date. 最低的开始日期加上最大的整数通常需要晚于最新的结束日期返回结果。 Typically, you need a lot more than five rows. 通常,您需要的行多于五行。 You've been warned. 您已被警告。

create table test (start date, end date);
insert into test values('2015-09-19','2015-09-22');
insert into test values('2015-09-19','2015-09-19');

-- Calendar from date range. Look at your query plan.
-- There might be a better way to do this. I think you're 
-- going to have to use a cross join with SQLite, though.
select distinct date(start, '+' || n || ' days') as cal_date
from test, integers 
order by cal_date;
cal_date  
----------
2015-09-19
2015-09-20
2015-09-21
2015-09-22
2015-09-23
2015-09-24
2015-09-25

Let's expand that a little to include the day of the week, and make it a view. 让我们稍微扩展一下以包括星期几,并使其成为视图。

-- Calendar view from date range
drop table calendar;
create view calendar as 
select distinct date(start, '+' || n || ' days') as cal_date,
       case strftime('%w', date(start, '+' || n || ' days')) 
       when 0 then 'Sun'
       when 1 then 'Mon'
       when 2 then 'Tue'
       when 3 then 'Wed'
       when 4 then 'Thu'
       when 5 then 'Fri'
       when 6 then 'Sat'
       end as day_of_week
from test, integers;

Now we can count the number of weekdays using a join and an aggregate function. 现在,我们可以使用联接和聚合函数计算工作日数。

select start, end, count(cal_date) as num_weekdays
from test
left join calendar on cal_date between start and end 
             and day_of_week in ('Mon', 'Tue', 'Wed', 'Thu', 'Fri')
group by start, end
order by start, end;
start       end         num_weekdays
----------  ----------  ------------
2015-09-19  2015-09-19  0           
2015-09-19  2015-09-22  2

Have a look at the Date and Time Functions of SQLite. 看看SQLite的日期和时间功能 Those are the ones that can be used as part of SQLite-internal queries. 这些可以用作SQLite内部查询的一部分。

Unfortunately, those are rather basic functions that can be used to map the String representation of a date to something else. 不幸的是,这些是相当基本的功能,可用于将日期的String表示形式映射到其他内容。 The julianday() function is the only one one could calculate differences in days with, but it would not care about Saturday and Sunday. julianday()函数是唯一可以计算天数差异的函数,但它并不关心星期六和星期日。

Maybe there could be an approach based on "day of the week" (0 == Sunday, 6 == Saturday) and using the "seconds since 1970-01-01" to come up with a conditional expression using the time-difference in seconds. 也许可能有一种基于“星期几”(0 ==星期日,6 ==星期六)并使用“自1970-01-01起的秒数”来得出条件表达式的方法,该条件表达式使用秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM