【问题标题】:adding recurring employee holidays in sql server在 sql server 中添加定期员工假期
【发布时间】:2012-09-13 23:59:09
【问题描述】:

我目前在 SQL Server 中有这个表:

PL_ID User_ID Log_Date Out_Time In_Time 原因详情

PL 代表人员记录器...然后您有用户 ID、日志日期(休息日)、外出时间、及时、原因和详细信息...有一个 ASP 前端允许用户将他们的休息日添加到其他人编写的表格中...目前用户能够自己执行此操作不是问题,但是,我的任务是为下一年增加员工休息日...。他们经常休假(每周一下午 1 点到 3 点)或(每周四 2 点到 5 点)……必须有一种更简单的方法来做到这一点,而不是一次只增加一天。我尝试过使用 dateadd 进行试验,但我无法弄清楚将其包含在插入中的语法...有一天我计划将其添加到用户页面,但现在我只需要让他们的休息日进入表格!抱歉有点虚,但我对此很陌生,如果我没有找到一种简单的方法来插入休息日,我将不得不在明年每周手动完成!

先谢谢各位了

汤姆。

【问题讨论】:

    标签: sql sql-server-2008-r2 datediff dateadd recurring-events


    【解决方案1】:

    如果您有一个主日期表,您可以简单地查询该表以获取明年的星期一和星期四,并且可以使用 Insert Select ... 语法。

    DECLARE @StartDate DateTime
    DECLARE @EndDate DateTime
    SET @StartDate = '1/1/2013'
    SET @EndDate = '12/31/2013'
    
    INSERT INTO DestinationTable(Date,StartTime,EndTime)
    SELECT DM.Date,
           CASE WHEN DATENAME(dw,DM.Date) = 'Thursday' THEN '1400'
                WHEN DATENAME(dw,DM.Date) = 'Monday' THEN '1300'
            END AS StartTime,
            CASE WHEN DATENAME(dw,DM.Date) = 'Thursday' THEN '1700'
                WHEN DATENAME(dw,DM.Date) = 'Monday' THEN '1500'
            END AS EndTime     
      FROM DateMaster DM
     WHERE DM.Date Between @StartDate AND @EndDate
       AND DATENAME(dw,DM.Date) IN ('Thursday','Monday')
    

    但是,如果您没有主日期表,那么我们可以循环整个年份并填写表格。

    DECLARE @StartDate DateTime
    DECLARE @EndDate DateTime
    DECLARE @DateVar DateTime
    
    SET @StartDate = '1/1/2013'
    SET @EndDate = '12/31/2013'
    SET @DateVar = @StartDate
    
    WHILE @DateVar <= @EndDate
    BEGIN 
         INSERT INTO DestinationTable(Date,StartTime,EndTime)
         SELECT @DateVar,
                CASE WHEN DATENAME(dw,@DateVar) = 'Thursday' THEN '1400'
                     WHEN DATENAME(dw,@DateVar) = 'Monday' THEN '1300'
                 END AS StartTime,
                CASE WHEN DATENAME(dw,@DateVar) = 'Thursday' THEN '1700'
                     WHEN DATENAME(dw,@DateVar) = 'Monday' THEN '1500'
                 END AS EndTime      
          WHERE DATENAME(dw,@DateVar) IN ('Thursday','Monday')
    
         SET @DateVar = DATEADD(d,1,@DateVar)
     END
    

    你可以通过跳过其他日子而不是仅仅增加一天来提高效率......

    CTE

    DECLARE @StartDate DateTime
    DECLARE @EndDate DateTime
    SET @StartDate = '1/1/2013'
    SET @EndDate = '12/31/2013'
    
    ;WITH DateMaster(Date)
    AS
    (
        SELECT @StartDate
         UNION ALL
        SELECT DATEADD(d,1,Date)
          FROM DateMaster
         WHERE DATEADD(d,1,Date) <= @EndDate 
        )
    
    
    INSERT INTO DestinationTable(Date,StartTime,EndTime)
    SELECT DM.Date,
           CASE WHEN DATENAME(dw,DM.Date) = 'Thursday' THEN '1400'
                WHEN DATENAME(dw,DM.Date) = 'Monday' THEN '1300'
            END AS StartTime,
            CASE WHEN DATENAME(dw,DM.Date) = 'Thursday' THEN '1700'
                WHEN DATENAME(dw,DM.Date) = 'Monday' THEN '1500'
            END AS EndTime     
      FROM DateMaster DM
     WHERE DM.Date >= @StartDate AND DM.Date <= @EndDate
       AND DATENAME(dw,DM.Date) IN ('Thursday','Monday')
    OPTION (MAXRECURSION 366) 
    

    【讨论】:

    • 真的不应该在 SQL Server 中使用BETWEEN(真的)与日期/时间值,尤其是(因为一些日期/时间特性)。如果您没有日期表,通常的结果是使用递归 CTE 生成它(产生一个“虚拟”表),这(可能)比通过循环迭代要好得多。
    • 感谢大家的快速回复!将在本周一早上进行测试。我以前有一些关于 case 语句的 SQL 经验,但数据库结构与我目前所处的环境完全不同。
    • 今天早上刚看了这个,我相信它会起作用的!但是 PL_ID 是自动定义并从 ASP 页面插入的……我怎样才能让它包含一个新的 PL_ID 呢?再次感谢!
    • PL_ID的数据类型是什么,创建新PL_ID的规则是什么。它是表中的标识还是您获得最大值然后递增并插入,或者它只是一个新的 guid?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-22
    • 2016-11-28
    • 2022-01-12
    • 2018-08-15
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    相关资源
    最近更新 更多