基于日期字段更新表而不使用带有sql的循环

Rya*_*n O 5 sql sql-server datetime loops

我创建了以下脚本来更新Microsoft SQL Server中的计划表.主键字段是日期时间,是日历上的各个日期.员工安排连续7天,我需要在每个星期一到星期日到年底之间的两个雇员之间轮换7天.我使用循环创建了以下脚本,并且正在寻找一种方法来完成它而不使用循环.谢谢!

DECLARE @z_start INT
DECLARE @z_date DATETIME

SET @z_date = '03/07/16'

WHILE(@z_date < '12/31/16')
BEGIN
    SET @z_start = 0

    WHILE(@z_start < 7) BEGIN
        UPDATE EmployeeOnCall
        SET employeeName = 'Jones, Jim'
        WHERE deptID = 25 AND weekDay = @z_date

        SET @z_date = DATEADD(dd, 1, @z_date)
        SET @z_start = @z_start + 1
    END

    SET @z_start = 0

    WHILE(@z_start < 7) BEGIN
        UPDATE EmployeeOnCall
        SET employeeName = 'Penton, Andy'
        WHERE deptID = 25 AND weekDay = @z_date

        SET @z_date = DATEADD(dd, 1, @z_date)
        SET @z_start = @z_start + 1
    END
END;
Run Code Online (Sandbox Code Playgroud)

Dan*_*eld 0

您可以使用DATEPARTCTE 来完成此操作。这是相关部分:

;with wkNum as (
    SELECT weekDay, EmployeeName, deptID, (DATEPART(wk, weekDay) / 2) % 2 as period 
    FROM EmployeeOnCall
)
UPDATE wkNum
SET employeename = CASE WHEN wkNum.period = 0 THEN 'Jones, Jim' ELSE 'Penton, Andy' END
Run Code Online (Sandbox Code Playgroud)

这个想法是确定现在是一年中的哪一周,将其除以 2,然后除以您正在处理的员工数量。这是一个测试脚本:

DECLARE @test TABLE (weekDay datetime, employeename varchar(50), deptID int);

DEClARE @startdate datetime = '2016-02-16';
declare @enddate datetime = '2016-12-31';

;with 
 N0 as (SELECT 1 as n UNION ALL SELECT 1)
,N1 as (SELECT 1 as n FROM N0 t1, N0 t2)
,N2 as (SELECT 1 as n FROM N1 t1, N1 t2)
,N3 as (SELECT 1 as n FROM N2 t1, N2 t2)
,N4 as (SELECT 1 as n FROM N3 t1, N3 t2)
,N5 as (SELECT 1 as n FROM N4 t1, N4 t2)
,N6 as (SELECT 1 as n FROM N5 t1, N5 t2)
,nums as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as num FROM N6)
INSERT @test (weekDay, deptID)
SELECT DATEADD(day,num-1,@startdate) as thedate, 25
FROM nums
WHERE num <= DATEDIFF(day,@startdate,@enddate) + 1


;with wkNum as (
SELECT weekDay, EmployeeName, deptID, (DATEPART(wk, weekDay) / 2) % 2 as period FROM @test
)
UPDATE wkNum
SET employeename = CASE WHEN wkNum.period = 0 THEN 'Jones, Jim' ELSE 'Penton, Andy' END

SELECT * FROM @test
Run Code Online (Sandbox Code Playgroud)

如果您有一个员工表可以从中提取,则可能会像这样展开:

DECLARE @emps TABLE (Name varchar(100));

INSERT @emps VALUES ('Dan'), ('Joe'), ('Asdf')

UPDATE eoc
SET employeename = emp.Name
FROM EmployeeOnCall eoc
INNER JOIN (SELECT ROW_NUMBER() OVER(ORDER BY Name) rn, Name FROM @emps) emp
ON ((DATEPART(wk, weekDay) / 2) % (SELECT COUNT(*) FROM @emps)) + 1 = emp.rn
Run Code Online (Sandbox Code Playgroud)