表格结构:
ID VersionID ShiftType Duration(Hr) FromDate ToDate
**********************************************************************
1 1 WORKING 12 20150702 20170528
2 1 WORKING 12 20150702 20170528
3 2 NOTWORKING 06 20170529 20170531
4 2 WORKING 06 20170529 20170531
5 2 NOTWORKING 06 20170529 20170531
6 2 WORKING 06 20170529 20170531
7 3 WORKING 08 20170601 0
8 3 NOTWORKING 08 20170601 0
9 3 WORKING 08 20170601 0
在这里你可以看到我有3个版本(1,2,3)的班次(如10天的白班和接下来20天的夜班等)。
目前的跟随班次将没有结束时间(第7,8和9行)。
例如,从20150702到20170528,我跟随版本1,总共24小时(1天),两班制工作,从20170529到20170531跟随版本2,四班制两个工作和两个非工作总共24小时(1天) )。
现在,如果用户提供日期范围,我应该在该日期范围内进行转换。
提供日期范围:从20170528到20170614。
预期结果:所有行。
使用以下查询:
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
但不起作用:从20170502到20170514。
预期结果:第1,2行(但未选中)。
但不起作用:从20170604到20170714。
预期结果:第7,8,9行(但未选中)。
谢谢。
答案 0 :(得分:1)
我们正在寻找3种截然不同的东西:
“查找完全包含在我的日期范围内的所有轮班”:
(FFROMDATE <= @StartDate AND FTODATE >= @EndDate)
查找与开始重叠的所有班次
(FFROMDATE >= @StartDate AND FFROMDATE <= @EndDate)
查找与结尾重叠的所有班次
(FTODATE >= @StartDate AND FTODATE <= @EndDate)
然后将它们组合成一个查询。
SELECT * FROM SHIFTS
WHERE
(FFROMDATE < @StartDate AND FTODATE > @EndDate) OR
(FFROMDATE >= @StartDate AND FFROMDATE <= @EndDate) OR
(FTODATE >= @StartDate AND FTODATE <= @EndDate)
请务必使用边界值对其进行测试,然后移除=
以符合您的具体要求。
答案 1 :(得分:1)
这适用于所有三种情况:
select *
from shifts
where fromdate <= range_end
and range_start <= case when todate = 0 then 99991231 else todate end
测试:
with shifts (id, fromdate, todate) as (
select 1, 20150702, 20170528 from dual union all
select 2, 20150702, 20170528 from dual union all
select 3, 20170529, 20170531 from dual union all
select 4, 20170529, 20170531 from dual union all
select 5, 20170529, 20170531 from dual union all
select 6, 20170529, 20170531 from dual union all
select 7, 20170601, 0 from dual union all
select 8, 20170601, 0 from dual union all
select 9, 20170601, 0 from dual ),
ranges (range_id, range_start, range_end) as (
select 1, 20170528, 20170614 from dual union all
select 2, 20170502, 20170514 from dual union all
select 3, 20170604, 20170714 from dual )
select *
from shifts cross join ranges
where fromdate <= range_end
and range_start <= case when todate = 0 then 99991231 else todate end
order by range_id, id
答案 2 :(得分:0)
oracle的解决方案:
org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g
对于SQL服务器:
您可以使用ISNULL或CASE代替NVL。我没有尝试使用sql server,因为我没有。