我需要在Oracle SQL中获取介于开始日期和结束日期之间的记录。我将具有varStartDate
和varEndDate
。我希望获取介于varStartDate
和varEndDate
之间的所有记录。我正在尝试下面的查询,首先我将获取最近的开始日期(即过去)和结束日期(即将来)。其次,一旦我有了开始日期和结束日期,我将获取所有startdate
〉=和enddate
〈=的记录。开始日期和结束日期是DATE
数据类型。
| 休假类型|开始日期|结束日期|休假次数|
| - ------|- ------|- ------|- ------|
| 年假|2021年10月8日|2021年10月8日|小行星24|
| 年假|二十一年十一月二十九日|二十一年十一月二十九日|小行星24043|
| 年假|二十一年十二月二十三日|二十一年十二月二十三日|小行星30069|
| 年假|二十一年十二月二十九日|二十一年十二月三十一日|小行星30112|
| 年假|2022年1月24日|2022年1月24日|小行星30189|
质询:
with RosterStartDate as (
select max(start_date) as START_DATE
from Payrollrecords
where START_DATE < TO_DATE('2021-11-20','YYYY-MM-DD')
),
RosterEndDate as (
select min(end_date) as END_DATE
from Payrollrecords where END_DATE >= TO_DATE('2022-11-30','YYYY-MM-DD')
)
select *
from Payrollrecords
where START_DATE = (select START_DATE from RosterStartDate)
and END_DATE = (select END_DATE from RosterEndDate)
如果RosterEndDate.END_DATE
为null
,则查询将不返回任何记录(如果在varEndDate
之后未找到结束日期,则查询将返回nul
l)。如果您能帮助我优化查询,那就太好了。
5条答案
按热度按时间cfh9epnr1#
你可以这样做:
yeotifhr2#
RosterStartDate为
08-OCT-21
,RosterEndDate为NULL。即使RosterEndDate不为null,但假设为23-DEC-21
,您也不会找到一行将两个日期都与你想要这个代替:
但由于END_DATE可以为空,因此您最终需要:
更容易写成
或者使用可能更快更清楚的不可达日期文字:
演示:https://dbfiddle.uk/taPsiGJw
brvekthn3#
我不确定是否正确理解了你问题的全部内容。
工资单记录表示日期间隔。您希望查找与间隔(RosterStartDate - RosterEndDate)相交的所有工资单记录,其中RosterEndDate可能为NULL。如果为NULL,我们可以使用
NVL()
函数将其替换为今天的值。因此,类似于以下内容的代码应该可以完成这项工作roqulrg34#
你的问题写得很混乱然而,从你评论来看,你似乎只是想:
如果日期包含时间部分,并且您希望2022 - 11 - 30为全天,则使用:
原始答案
如果使用分析函数,则可以消除所有子查询。
如果要使所有范围完全包含在范围内,则:
如果您希望范围与该范围重叠,则:
fiddle
aij0ehis5#
我建议您在数据中包含一个end_date为NULL的行,如下所示:
| 休假类型|开始日期|结束日期|休假编号|
| - ------|- ------|- ------|- ------|
| 年假|2021年10月8日|2021年10月8日|小行星24|
| 年假|2021年11月21日|二十一年十一月二十九日|小行星24043|
| 年假|二十一年十二月二十三日|二十一年十二月二十三日|小行星30069|
| 年假|二十一年十二月二十三日|* 无效 *|小九九九九九|
| 年假|二十一年十二月二十九日|二十一年十二月三十一日|小行星30112|
| 年假|2022年1月24日|2022年1月24日|小行星30189|
| 休假类型|开始日期|结束日期|休假编号|
| - ------|- ------|- ------|- ------|
| 年假|2021年11月21日|二十一年十一月二十九日|小行星24043|
| 年假|二十一年十二月二十三日|二十一年十二月二十三日|小行星30069|
| 年假|二十一年十二月二十三日|* 无效 *|小九九九九九|
| 年假|二十一年十二月二十九日|二十一年十二月三十一日|小行星30112|
| 年假|2022年1月24日|2022年1月24日|小行星30189|
请参见此fiddle
注:
1.比较start_date和range_end,以及end_date和range_start看起来似乎违反直觉,但是这种方法有效并且简化了所需的 predicate
1.当您在CTE中包含日期文字时,只需在where子句中使用相同的文字并避免CTE-绑定变量在这里也可以工作
1.要考虑NULL,请添加"或end_date ISNULL",并使用适当的括号,不要在 predicate 中使用NVL或COALESCE,因为这些函数可能对查询性能有害。