我在SQL中找到了做日期差异问题的一些答案,不包括周末和假日。我的问题是我需要进行日期比较 - 有多少子记录的工作日期是在父记录的发送日期的三天内?
大多数日期差异答案都涉及一个日历表,我想如果我可以构建一个返回日期+3的子选择,我可以解决剩下的问题。但我无法弄清楚如何返回日期+3。
所以:
CREATE TABLE calendar
(
thedate DATETIME NOT NULL,
isweekday SMALLINT NULL,
isholiday SMALLINT NULL
);
和
SELECT thedate AS fromdate, xxx AS todate
FROM calendar
我想要的是todate从72小时开始,不包括周末和假日。做一个COUNT(*),其中isweekday而不是isholiday很简单,但做一个DATEADD()是另一回事。
我不知道从哪里开始。
答案 0 :(得分:1)
修改强> 已更改为将非工作日包含为有效日期。
WITH rankedDates AS
(
SELECT
thedate
, ROW_NUMBER()
OVER(
ORDER BY thedate
) dateRank
FROM
calendar c
WHERE
c.isweekday = 1
AND
c.isholiday = 0
)
SELECT
c1.fromdate
, rd2.thedate todate
FROM
(
SELECT
c.thedate fromDate
,
(
SELECT
TOP 1 daterank
FROM
rankedDates rd
WHERE
rd.thedate <= c.thedate
ORDER BY
thedate DESC
) dateRank
FROM
calendar c
) c1
LEFT JOIN
rankedDates rd2
ON
c1.dateRank + 3 = rd2.dateRank
您可以在日历表上添加日期排名列以简化此操作并避免使用CTE:
CREATE TABLE
calendar
(
TheDate DATETIME PRIMARY KEY
, isweekday BIT NOT NULL
, isHoliday BIT NOT NULL DEFAULT 0
, dateRank INT NOT NULL
);
然后,您只需将daterank列设置为非假日工作日。
答案 1 :(得分:1)
这应该可以解决问题,将“顶部”中的数字更改为您想要包含的天数。
declare @date as datetime
set @date = '5/23/13'
select
max(_businessDates.thedate)
from (
select
top 3 _Calendar.thedate
from calendar _Calendar
where _Calendar.isWeekday = 1
and _Calendar.isholiday = 0
and _Calendar.thedate >= @date
order by
_Calendar.thedate
) as _businessDates
对于可以前进或后退一定天数的动态版本,请尝试以下操作:
declare @date as datetime
declare @DayOffset as int
set @date = '5/28/13'
set @DayOffset = -3
select
(case when @DayOffset >= 0 then
max(_businessDates.thedate)
else
min(_businessDates.thedate)
end)
from (
select
top (abs(@DayOffset) + (case when @DayOffset >= 0 then 1 else 0 end)) _Calendar.thedate
from calendar _Calendar
where _Calendar.isWeekday = 1
and _Calendar.isholiday = 0
and ( (@DayOffset >= 0 and _Calendar.thedate >= @date)
or (@DayOffset < 0 and _Calendar.thedate < @date) )
order by
cast(_Calendar.thedate as int) * (case when @DayOffset >=0 then 1 else -1 end)
) as _businessDates
您可以将@DayOffset设置为正数或负数。
答案 2 :(得分:0)
你只需要DATEADD,除非我不理解你的问题。
DATEADD(DAY,3,没有fromdate)
编辑:我看到,不计算周末或假期,会暂时更新。
更新:看起来好像Jason钉了它,但是如果你有机会使用SQL2012,这是简单的版本:
SELECT todate = thedate
fromdate = LEAD(thedate,3) OVER (ORDER BY thedate)
FROM calendar
WHERE isweekday = 1
AND isHoliday = 0
答案 3 :(得分:0)
如果您需要使用dateAdd:
作为查询,请尝试此操作SELECT
allDates.thedate fromDate
,min(nonWeekendHoliday.thedate) toDate
FROM (
SELECT
thedate
FROM
calendar _calendar
) allDates
LEFT JOIN (
SELECT
thedate
FROM
calendar _calendar
WHERE
_calendar.isweekday = 1
AND
_calendar.isholiday = 0
) nonWeekendHoliday
on dateadd(d,3,allDates.thedate) <= nonWeekendHoliday.thedate
where allDates.thedate between '5/20/13' and '5/31/13'
group by
allDates.thedate