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字段中(这就是它们的用途!),而不是作为数字或字符串。如果这样做,则更容易在日期之间进行适当和准确的比较。