我正在尝试提取在2个工作日内到期的活动的所有活动结束日期。因此,对于星期五和星期四,我希望日期在4天或更短时间内结束,星期六日期在3天内结束,太阳星期三日期在2天内结束,+ 3表示所有公共假日,列在日期列中的tempdate
以下脚本不起作用,只接受+2天的日期。我理解我需要使用case语句,但我真的不明白如何实现它。有人有什么想法吗?
select event_end_date
from mdmins.table
/*separating by date to find expiring dates*/
where ( (dayofweek(c.event_end_date) in (5,6) /*Friday & Thursday*/
and date(c.event_end_date) < current_date + 4 days
and date(c.event_end_date) >= current_date)
or (dayofweek(c.event_end_date) in (1,2,3,4) /*All other days of week*/
and date(c.event_end_date) < current_date + 2 days
and date(c.event_end_date) >= current_date)
or (dayofweek(c.event_end_date) = 7 /*Saturday - not that this should be needed, but just in case*/
and date(c.event_end_date) < current_date + 3 days
and date(c.event_end_date) >= current_date)
or (date(c.event_end_date) < (select dateval from mdmins.tempdate where dateval = (current date + 3 days)) /*a holiday is on in 3 days, so 2 working days before*/
and date(c.event_end_date) >= current_date) )
答案 0 :(得分:0)
从逻辑上讲,本周数据之间唯一不同的是你看多远,所以使用案例限制逻辑:
...
where date(c.event_end_date) between current_date and current_date +
case
when dayofweek(c.event_end_date) in (5, 6) then 4
when dayofweek(c.event_end_date) in (1, 2, 3, 4) then 2
else 3
end days
or (date(c.event_end_date) < (select dateval
from mdmins.tempdate
where dateval = (current date + 3 days))
and date(c.event_end_date) >= current_date)
答案 1 :(得分:0)
where ((date(c.event_end_date) between current_date and current_date +
case
when dayofweek(current date) in (5,6) then 4
when dayofweek(current date) in (1, 2, 3, 4) then 2
else 3
end days)
or date(c.event_end_date) < (select dateval
from mdmins.tempdate
where dateval = (current date + 3 days))
and date(c.event_end_date) >= current_date )
答案 2 :(得分:0)
这是一个典型的例子,说明为什么你想要一个包含所有日期的日历,以及一堆额外的信息。你能够做类似的事情:
WITH Desired_Dates AS (SELECT MIN(calendarDate) AS startRange,
MAX(calendarDate) + 1 DAY AS endRange
FROM(SELECT calendarDate
FROM Calendar
WHERE calendarDate >= CURRENT_DATE
AND dayOfWeekISO IN (1, 2, 3, 4, 5)
AND isHolday = '0'
ORDER BY calendarDate
FETCH FIRST 3 ROWS ONLY) D)
SELECT C.<column_list
FROM <Your_Table> C
JOIN Desired_Dates D
ON C.event_end_date >= D.startRange
AND C.event_end_Date < D.endRange
(请注意,我特别使用ISO星期几,其中星期一是1.星期日,因为1是美国的东西,并且函数来推导星期几从给定日期开始受到当前文化设置的影响。同样,如果event_end_date
类似于时间戳,则需要使用专用结束范围
这实际上有可能使用仅索引信息来获取所需的日期(假设相关索引),并且在任何情况下都只会获取CTE中的数据一次。
如果您没有日历表,可以制作一个:
WITH Working_Dates AS (SELECT CURRENT_DATE - 1 DAY AS calendarDate,
0 AS workingDayNum, '0' AS isWorkingDay
FROM SYSIBM/SYSDUMMY1
UNION ALL
SELECT calendarDate,
workingDayNum + CASE WHEN isWorkingDay = 1
THEN 1
ELSE 0 END AS workingDayNum,
isWorkingDay
FROM (SELECT calendarDate, workingDayNum,
CASE WHEN DAYOFWEEK_ISO(WD.calendarDate) IN (6, 7)
OR Holiday.dateval IS NOT NULL
THEN '0'
ELSE '1' END AS isWorkingDay
FROM (SELECT calendarDate + 1 DAY, workingDayNum
FROM Working_Dates
WHERE workingDayNum < 2) WD
LEFT JOIN mdmins.tempdate Holiday
ON Holiday.dateval = WD.calendarDate) WD),
Desired_Dates AS (SELECT MIN(calendarDate) AS startRange,
MAX(calendarDate) + 1 DAY AS endRange
FROM Working_Date
WHERE isWorkingDay = '1')
SELECT C.<column_list
FROM <Your_Table> C
JOIN Desired_Dates D
ON C.event_end_date >= D.startRange
AND C.event_end_Date < D.endRange
这是使用递归CTE循环从当前日期(一个之前)到三个工作日过去的天数。 (我必须提前一天开始,所以我只需要写#34;它是一个工作日&#34;逻辑一次,这也是所有嵌套的原因。)
请注意,您的原始尝试或任何现有答案都不考虑这些:
通过建立实际工作日的清单,我们可以将自己与问题隔离开来。