Sql 如何从给定日期范围所在的数据库中选择行?

Sql 如何从给定日期范围所在的数据库中选择行?,sql,oracle,Sql,Oracle,表格结构: ID VersionID ShiftType Duration(Hr) FromDate ToDate ********************************************************************** 1 1 WORKING 12 20150702 20170528 2 1 WORKING 12

表格结构:

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
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
SELECT * FROM SHIFTS
WHERE FFROMDATE<=20170614 AND (FTODATE>=20170528 OR NVL(FTODATE,0)=0)
在这里你可以看到我有3个版本的班次(1,2,3)(比如10天的白班和接下来20天的夜班等等)

当前跟随班次将没有结束时间(第7、8和9行)

例如,从20150702年到20170528年,我遵循的是第1版,共24小时(1天),两班制工作;从20170529年到20170531年,我遵循的是第2版,共24小时(1天)四班制,两班制工作,两班制不工作

现在,如果用户提供日期范围,我应该得到该日期范围内的班次

提供的日期范围:从20170528到20170614

预期结果:所有行

处理以下查询:

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
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
SELECT * FROM SHIFTS
WHERE FFROMDATE<=20170614 AND (FTODATE>=20170528 OR NVL(FTODATE,0)=0)
从班次中选择*

其中(FFROMDATE>=20170528和FFROMDATE=20170528和FTODATE我们要寻找三种不同的东西:

“查找完全包含在我的日期范围内的所有班次”:

(FFROMDATE=@EndDate)
查找与起点重叠的所有班次

(FFROMDATE >= @StartDate AND FFROMDATE <= @EndDate)
(FFROMDATE>=@StartDate和FFROMDATE=@StartDate和FTODATE@EndDate)或

(FFROMDATE>=@StartDate和FFROMDATE=@StartDate和FTODATE我们在寻找三种不同的东西:

“查找完全包含在我的日期范围内的所有班次”:

(FFROMDATE=@EndDate)
查找与起点重叠的所有班次

(FFROMDATE >= @StartDate AND FFROMDATE <= @EndDate)
(FFROMDATE>=@StartDate和FFROMDATE=@StartDate和FTODATE@EndDate)或

(FFROMDATE>=@StartDate和FFROMDATE=@StartDate和FTODATE这适用于所有三种情况:

select * 
  from shifts
  where fromdate <= range_end 
    and range_start <= case when todate = 0 then 99991231 else todate end
选择*
轮班

其中fromdate适用于所有三种情况:

select * 
  from shifts
  where fromdate <= range_end 
    and range_start <= case when todate = 0 then 99991231 else todate end
选择*
轮班

其中fromdate针对oracle的解决方案:

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
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
SELECT * FROM SHIFTS
WHERE FFROMDATE<=20170614 AND (FTODATE>=20170528 OR NVL(FTODATE,0)=0)
从班次中选择*
其中,FFROMDATE=20170528或NVL(FTODATE,0)=0)
对于SQL server:

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
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
SELECT * FROM SHIFTS
WHERE FFROMDATE<=20170614 AND (FTODATE>=20170528 OR NVL(FTODATE,0)=0)

您可以使用ISNULL或CASE代替NVL。我没有在sql server上尝试,因为我没有它。

oracle解决方案:

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
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
SELECT * FROM SHIFTS
WHERE FFROMDATE<=20170614 AND (FTODATE>=20170528 OR NVL(FTODATE,0)=0)
从班次中选择*
其中,FFROMDATE=20170528或NVL(FTODATE,0)=0)
对于SQL server:

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
SELECT * FROM SHIFTS
WHERE (FFROMDATE >= 20170528 AND FFROMDATE <= 20170614) OR (FTODATE >= 20170528 AND FTODATE <= 20170614)
SELECT * FROM SHIFTS
WHERE FFROMDATE<=20170614 AND (FTODATE>=20170528 OR NVL(FTODATE,0)=0)

您可以使用ISNULL或CASE代替NVL。我没有在sql server上尝试,因为我没有它。

您使用的是MySQL、MS sql server还是Oracle?不要标记未涉及的产品。(所有这些都有不同的日期/时间处理…)这些日期字段是实际的日期时间字段,还是字符串(urgh)?这是什么数据库?sql server需要引用日期值,所以我猜是另一个database@jarlh,GuidoG为什么这里有什么数据库重要?…我使用mysql、oracle和python这三种数据库,这取决于我构建的应用程序和其他原因。该解决方案可以帮助所有三个db用户。“该解决方案可以帮助所有三个db用户”。不一定,因为正如前面提到的,它们处理日期的方式都不同。而且实际上,您应该在DateTime字段中存储日期(这就是它们的用途!)而不是作为数字或字符串。如果这样做,就更容易在日期之间进行适当和准确的比较。您使用的是MySQL、MS SQL Server或Oracle吗?不要标记未涉及的产品。(所有这些产品都有不同的日期/时间处理…)这些日期字段是实际的日期时间字段,还是字符串(urgh)?这是什么数据库?sql server需要引用日期值,所以我猜是另一个database@jarlh,GuidoG为什么这里有什么数据库重要?…我使用mysql、oracle和python这三种数据库,这取决于我构建的应用程序和其他原因。该解决方案可以帮助所有三个db用户。“该解决方案可以帮助所有三个db用户”。不一定,因为如上所述,它们处理日期的方式都不同。实际上,您应该将日期存储在DateTime字段中(这就是它们的用途!),而不是作为数字或字符串。如果这样做,则更容易在日期之间进行适当和准确的比较。