SQL获取下一个日期时间

时间:2015-02-05 07:20:15

标签: sql sql-server

我在SQL SERVER中有3个表

  1. 工作
  2. JobID LastRunDateTime
    1     01/02/2015
    2     05/02/2015
    3     20/01/2015
    
    1. JobsDays - 工作需要运行的日子
    2. JobID DayNum
      1     1
      1     2
      1     5
      2     2
      2     6
      3     1
      3     2
      3     3
      
      1. JobTimes - 工作需要运行的小时数
      2. 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
        

        我得到下一个运行日期,但我需要下次运行的完整日期时间。

        由于

2 个答案:

答案 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