Sql server SQL:生成不同频率的计划表

Sql server SQL:生成不同频率的计划表,sql-server,Sql Server,我在SQL Server 2012中工作。我有三张桌子。第一个是“时间表”表。其结构如下: CREATE TABLE schedule ( JobID int ,BeginDate date ,EndDate date ) CREATE TABLE frequency ( JobID int ,RunDay varchar(9) ) CREATE TABLE calendar ( CalendarFullDate date ,DayNa

我在SQL Server 2012中工作。我有三张桌子。第一个是“时间表”表。其结构如下:

CREATE TABLE schedule
(
    JobID int
    ,BeginDate date
    ,EndDate date
)
CREATE TABLE frequency
(
    JobID int
    ,RunDay varchar(9)
)
CREATE TABLE calendar
(
    CalendarFullDate date
    ,DayName varchar(9)
)
一些样本数据是:

INSERT INTO schedule
SELECT 1, '2017-01-01', '2017-07-31' UNION ALL
SELECT 2, '2017-02-01', '2017-06-30'
INSERT INTO frequency
SELECT 1, 'Sunday' UNION ALL
SELECT 1, 'Monday' UNION ALL
SELECT 1, 'Tuesday' UNION ALL
SELECT 1, 'Wednesday' UNION ALL
SELECT 1, 'Thursday' UNION ALL
SELECT 1, 'Friday' UNION ALL
SELECT 1, 'Saturday' UNION ALL
SELECT 2, 'Wednesday'
第二个是“频率”表。其结构如下:

CREATE TABLE schedule
(
    JobID int
    ,BeginDate date
    ,EndDate date
)
CREATE TABLE frequency
(
    JobID int
    ,RunDay varchar(9)
)
CREATE TABLE calendar
(
    CalendarFullDate date
    ,DayName varchar(9)
)
一些样本数据是:

INSERT INTO schedule
SELECT 1, '2017-01-01', '2017-07-31' UNION ALL
SELECT 2, '2017-02-01', '2017-06-30'
INSERT INTO frequency
SELECT 1, 'Sunday' UNION ALL
SELECT 1, 'Monday' UNION ALL
SELECT 1, 'Tuesday' UNION ALL
SELECT 1, 'Wednesday' UNION ALL
SELECT 1, 'Thursday' UNION ALL
SELECT 1, 'Friday' UNION ALL
SELECT 1, 'Saturday' UNION ALL
SELECT 2, 'Wednesday'
第三个是“日历”表。其结构如下:

CREATE TABLE schedule
(
    JobID int
    ,BeginDate date
    ,EndDate date
)
CREATE TABLE frequency
(
    JobID int
    ,RunDay varchar(9)
)
CREATE TABLE calendar
(
    CalendarFullDate date
    ,DayName varchar(9)
)
我的目标是“取消Pivot”时间表,以便为每个JobID的BeginDate和EndDate中跨越日期范围的每个日期创建一行。行必须与每个作业ID的频率表中的天数相匹配

到目前为止,每项工作的日期频率为每日或每周。为此,我使用以下SQL生成所需的表:

SELECT
    s.JobID
    ,c.CalendarFullDate
FROM
    schedule AS s
INNER JOIN
    calendar AS c
ON
    c.CalendarFullDate BETWEEN s.BeginDate AND s.EndDate
INNER JOIN
    frequency AS f
ON
    f.JobID = s.JobID
    AND f.RunDay = c.DayName
这不适用于高于每周(例如,每两周)的频率。为此,我知道我的频率表需要改变结构。特别是,我必须添加一个列,给出频率(例如,每日、每周、双周)。而且,我打赌我还需要在日历表中添加一个周数列

如何生成所需的表格以容纳至少两周一次的频率(如果不是更高的频率)?例如,如果JobID=3是一个在周三运行的双周作业,并且它的绑定条件是BeginDate='2017-06-01'和EndDate='2017-07-31',那么,对于此作业,我希望得到以下结果:

JobID    Date
3        2017-06-07
3        2017-06-21
3        2017-07-05
3        2017-07-19

我更改了时间表而不是频率表。我添加了一个SkipWeeks字段,对于每两周一次,该字段应设置为1;对于每三周运行一次作业,该字段应设置为2。我使用了一个表值函数来返回正确的日期。我想这就是你想要的

CREATE TABLE dbo.schedule
(
    JobID int
    ,BeginDate date
    ,EndDate date
    ,SkipWeeks tinyint default 0
)
GO
INSERT INTO dbo.schedule
(JobID,BeginDate,EndDate)
SELECT 1, '2017-01-01', '2017-07-31' UNION ALL
SELECT 2, '2017-02-01', '2017-06-30'
GO
CREATE TABLE dbo.frequency
(
    JobID int
    ,RunDay varchar(9),
    primary key (
        JobID,
        RunDay
    )
)
GO
INSERT INTO dbo.frequency
SELECT 1, 'Sunday' UNION ALL
SELECT 1, 'Monday' UNION ALL
SELECT 1, 'Tuesday' UNION ALL
SELECT 1, 'Wednesday' UNION ALL
SELECT 1, 'Thursday' UNION ALL
SELECT 1, 'Friday' UNION ALL
SELECT 1, 'Saturday' UNION ALL
SELECT 2, 'Wednesday'
GO
CREATE FUNCTION dbo.DateRangeTable(@pdStartDate date, @pdEndDate date, @piSkipWeeks tinyint)
RETURNS 
@dates TABLE 
(
    [Date] date primary key,
    DayName varchar(9)
)
AS
BEGIN
    declare @ldDate date = @pdStartDate
    declare @skipDecr smallint = @piSkipWeeks
    while (@ldDate <= @pdEndDate) Begin
        if @skipDecr = 0 Begin
            insert into @dates
            select @ldDate, format(@ldDate,'dddd')
        End
        --Start of New week? (% = MOD)
        if datediff(d,@pdStartDate,@ldDate) % 7 = 0 Begin 
            if @skipDecr = 0 Begin
                set @skipDecr = @piSkipWeeks
            End else Begin
                set @skipDecr = @skipDecr - 1
            End
        End
        set @ldDate = dateadd(D,1, @ldDate)
    End

    RETURN 
END
GO
INSERT INTO dbo.schedule
(JobID,BeginDate,EndDate,SkipWeeks)
SELECT 3, '2017-06-01','2017-07-31',1 
GO
INSERT INTO dbo.frequency
SELECT 3, 'Wednesday'
GO
SELECT
    s.JobID
    ,c.[Date]
FROM dbo.schedule AS s
cross apply dbo.DateRangeTable(s.BeginDate, s.EndDate, s.SkipWeeks) c
INNER JOIN dbo.frequency AS f
ON f.JobID = s.JobID
    AND f.RunDay = c.DayName
GO
创建表dbo.schedule
(
JobID int
,开始日期
,结束日期
,SkipWeeks tinyint默认值为0
)
去
插入到dbo.schedule中
(JobID,BeginDate,EndDate)
选择1,'2017-01-01','2017-07-31'联合所有
选择2,‘2017-02-01’、‘2017-06-30’
去
创建表dbo.frequency
(
JobID int
,RunDay varchar(9),
主键(
若比德,
跑步日
)
)
去
插入dbo.frequency
选择1,“星期日”联合所有
选择1,“星期一”联合所有
选择1,“星期二”联合所有
选择1,“星期三”联合所有
选择1,“星期四”联合所有
选择1,“星期五”联合所有
选择1,“星期六”联合所有
选择2,‘星期三’
去
创建函数dbo.DateRangeTable(@pdStartDate date、@pdEndDate date、@piSkipWeeks tinyint)
返回
@日期表
(
[日期]日期主键,
DayName varchar(9)
)
作为
开始
声明@ldDate日期=@pdStartDate
声明@skipDecr smallint=@piSkipWeeks

while(@ldDate)您能提供样本数据和预期结果吗?只是(稍微)提供了一些。