我在SQL SERVER中有3个表
JobID LastRunDateTime
1 01/02/2015
2 05/02/2015
3 20/01/2015
JobID DayNum
1 1
1 2
1 5
2 2
2 6
3 1
3 2
3 3
JobID TimeNum
1 12
1 13
2 10
2 20
3 7
我需要计算下次工作需要运行的时间。
我开始找到下一个日期(没有时间):
DECLARE @CurrentDateTime DATETIME
SET @CurrentDateTime = GETDATE()
SELECT j.JobID,
MIN(DATEADD(DAY, (DATEDIFF(DAY, ((jday.DayNum + 5 ) % 7 ), @CurrentDateTime) / 7) * 7 + 7, ((jday.DayNum + 5 ) % 7)))
AS NEXTDATE
FROM Jobs j
JOIN JobDays jday on j.JobID = jday.JobID
group by j.JobID
我得到下一个运行日期,但我需要下次运行的完整日期时间。
由于
答案 0 :(得分:1)
我将从本周的第一天开始:
SET DATEFIRST 1;
DECLARE @WeekStart DATETIME = DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE));
今天(2月5日)运行的时间为2015-02-05
然后,您将需要每个工作的日期和时间的笛卡尔积,例如:对于工作1,你最终会得到:
DayNum Time
---------------
1 12
1 13
2 12
2 13
5 12
5 13
这可以通过使用
来完成SELECT d.DayNum, t.TimeNum
FROM Jobdays AS d
INNER JOIN JobTimes AS t
ON t.JobID = d.JobID
WHERE d.JobID = 1
然后只是将这些日期和时间添加到本周开始的情况:
DayNum TimeNume Date/Time
---------------------------------------
1 12 2015-02-03 12:00:00
1 13 2015-02-03 13:00:00
2 12 2015-02-04 12:00:00
2 13 2015-02-04 13:00:00
5 12 2015-02-07 12:00:00
5 13 2015-02-07 13:00:00
使用:
DATEADD(HOUR, t.TimeNum, DATEADD(DAY, d.DayNum - 1, @WeekStart))
问题是,在本周末,您最终会在下周找到下一个运行日期,因此您需要通过添加其他联接来生成两周的日期和时间:
SELECT d.DayNum,
t.TimeNum,
RunDateTime = DATEADD(WEEK, w.WeekNum, DATEADD(HOUR, t.TimeNum, DATEADD(DAY, d.DayNum - 1, @WeekStart)))
FROM Jobdays AS d
INNER JOIN JobTimes AS t
ON t.JobID = d.JobID
CROSS JOIN (VALUES (0), (1)) AS w (WeekNum)
WHERE d.JobID = 1;
所以把它们放在一起,你最终得到了
DECLARE @WeekStart DATETIME = DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE));
WITH JobDays AS
( SELECT JobID, DayNum
FROM (VALUES (1, 1), (1, 2), (1, 5), (2, 2), (2, 6), (3, 1), (3, 2), (3, 3)) t (JobID, DayNum)
), JObTimes AS
( SELECT JObID, TimeNum
FROM (VALUES (1, 12), (1, 13), (2, 10), (2, 20), (3, 7)) t (JobID, TimeNum)
), RunDates AS
( SELECT d.JobID,
RunDateTime = DATEADD(WEEK, w.WeekNum, DATEADD(HOUR, t.TimeNum, DATEADD(DAY, d.DayNum - 1, @WeekStart)))
FROM Jobdays AS d
INNER JOIN JobTimes AS t
ON t.JobID = d.JobID
CROSS JOIN (VALUES (0), (1)) AS w (WeekNum)
)
SELECT JobID,
NextRunDateTime = MIN(RunDateTime),
NextRunDate = CAST(MIN(RunDateTime) AS DATE),
NextRunTime = CAST(MIN(RunDateTime) AS TIME)
FROM RunDates
WHERE RunDateTime > GETDATE()
GROUP BY JobID;
给出了:
JobID | NextRunDateTime | NextRunDate| NextRunTime
------+---------------------+------------+---------
1 | 2015-02-05 12:00:00 | 2015-02-05 | 12:00:00
2 | 2015-02-06 10:00:00 | 2015-02-06 | 10:00:00
3 | 2015-02-08 07:00:00 | 2015-02-08 | 07:00:00
答案 1 :(得分:0)
这里你去..写为:
DATEPART(HH,GETDATE())
+ (MIN(jTime.TimeNum -DATEPART(HH,GETDATE())))AS NEXTTIME
为:
SELECT distinct Job.JobID,
MIN(DATEADD(DAY, (DATEDIFF(DAY, ((jday.DayNum + 5 ) % 7 )
, @CurrentDateTime) / 7) * 7 + 7, ((jday.DayNum + 5 ) % 7)))
AS NEXTDATE
,DATEPART(HH,GETDATE())
+ (MIN(jTime.TimeNum -DATEPART(HH,GETDATE())))AS NEXTTIME
FROM @Jobs job
JOIN @JobsDays jday on job.JobID = jday.JobID
JOIN @JobsTimes jTime ON jday.JobID = jTime.JobID
group by job.JobID