查找员工按日期名称日期范围之间移

时间:2019-02-02 06:38:05

标签: sql sql-server sql-server-2012

我有以下三个表

表HrShift:

Id  ShiftName       DaysOfWeek                                          StartTime   EndTime     StartDate   EndDate
1   Day Shift-1     Sunday,Monday,Tuesday,Wednesday,Thursday,Friday     09:00 AM    06:00 PM    2016-01-01  NULL
2   Day Shift-2     Sunday,Monday,Tuesday,Wednesday,Thursday,Friday     10:00 AM    07:00 PM    2010-01-01  NULL
3   Day Shift-3     Sunday,Monday,Tuesday,Wednesday,Thursday,Friday     11:00 AM    08:00 PM    2010-01-01  NULL

表ShiftType:

Id  Name
1   Primary
2   Roster

表EmployeeShifts:

Id  EmpId   HrShiftId   ShiftTypeId     StartDate   EndDate 
1   1       1           1               2018-01-01  NULL    
2   1       2           2               2018-02-01  2018-02-01
3   2       1           1               2018-01-01  NULL
4   2       2           2               2018-02-01  2018-02-01
5   2       3           2               2018-02-01  2018-02-01

创建表命令:

CREATE TABLE [HrShifts](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ShiftName] [nvarchar](max) NULL,
    [DaysOfWeek] [nvarchar](max) NULL,
    [StartTime] [nvarchar](max) NULL,
    [EndTime] [nvarchar](max) NULL,
    [StartDate] [datetime] NOT NULL,
    [EndDate] [datetime] NULL);

CREATE TABLE [ShiftType](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL);

CREATE TABLE [EmployeeShifts](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [EmpId] [int] NOT NULL,
    [HrShiftId] [int] NOT NULL,
    [ShiftTypeId] [int] NOT NULL,
    [StartDate] [datetime] NOT NULL,
    [EndDate] [datetime] NULL);

我需要找到两个日期之间的每个雇员单个分配移。 ShiftType花名册的优先级高于Primary。需要检查在HrShift表DaysOfWeek列具有由天名的日期相匹配。

(2018年1月31日2018年2月2日和)之间预期的结果是以下

Date        EmpId   ShiftType   HrShiftId   ShiftName       StartTime   EndTime
2018-01-31  1       1           1           Day Shift-1     09:00 AM    06:00 PM
2018-02-01  1       2           2           Day Shift-2     10:00 AM    07:00 PM
2018-02-02  1       1           1           Day Shift-1     09:00 AM    06:00 PM
2018-01-31  2       1           1           Day Shift-1     09:00 AM    06:00 PM
2018-02-01  2       2           2           Day Shift-2     10:00 AM    07:00 PM
2018-02-02  2       2           3           Day Shift-3     11:00 AM    08:00 PM

2 个答案:

答案 0 :(得分:1)

首先,您需要生成日期。为此,您可以使用递归CTE(或日历表)或类似方法。

new_item2.pdf

我认为with days as ( select convert(date, '2018-01-31') as dte union all select dateadd(day, 1, dte) from days where dte < '2018-02-02' ) select d.dte, es.*, hs.startTime, hs.endTime from EmployeeShifts es join HrShift hs on es.HrShiftId = hs.id cross join days d where d.dte >= hs.startDate and (d.dte < hs.endDate or hs.endDate is null) and hs.daysofweek like '%' + datename(weekday, d.dte) + '%'; 子句涵盖了您想要的日期和时间表之间的所有匹配逻辑。

答案 1 :(得分:0)

我更改了一些数据值以向您显示不同的结果: 用您的临时变量名更改。

在这里我首先输入日期列表@S_Date@E_Date是输入:

    DECLARE @S_Date AS DATETIME
    DECLARE @E_Date AS DATETIME
    DECLARE @TotalDays AS INT
    DECLARE @DisplayDate AS VARCHAR(50)
    DECLARE @WDN AS INT
    DECLARE @WDName AS VARCHAR(20)

    SET @S_Date =CONVERT(datetime,'01/31/2019')
    SET @E_Date =CONVERT(datetime,'02/02/2019')
    SET @WDN = DATEPART(WEEKDAY,@S_Date)
    SET @WDName = DATENAME(weekday,@S_Date)
    SET @TotalDays = DATEDIFF(dd,@S_Date, DATEADD(dd,1,@E_Date))
    SET @DisplayDate =  DATENAME(weekday, @S_Date)+' ' + DATENAME(dd,@S_Date)+' '+ DATENAME(m, @S_Date)+' '+ DATENAME(yy, @S_Date)


    CREATE TABLE #Monthdaytable(
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [DisplayDate] [varchar](50) NULL,
        [Actualdate] [datetime] NULL,
        [Week_Day_Number] INT NULL,
        [Week_Day_Name] VARCHAR(20) NULL
    ) ON [PRIMARY]

    DECLARE @i AS INT
    SET @i = 1  
    WHILE(@i<=@TotalDays)
    BEGIN
        INSERT INTO #Monthdaytable
                ( DisplayDate, ActualDate ,Week_Day_Number, Week_Day_Name)
        VALUES  (@DisplayDate, @S_Date, @WDN, @WDName)
        SET @S_Date = DATEADD(dd,1,@S_Date)
        SET @WDN = DATEPART(WEEKDAY,@S_Date)
        SET @WDName = DATENAME(weekday,@S_Date)
        SET @DisplayDate =DATENAME(weekday, @S_Date)+' ' + DATENAME(dd,@S_Date)+' '+  DATENAME(m, @S_Date)+' '+ DATENAME(yy, @S_Date)
        SET @i = @i+1
    END

只需您的桌子:

    CREATE TABLE #HrShift (Id int, ShiftName varchar(50), DaysOfWeek varchar(500),StartTime time(7),EndTime time(7), StartDate datetime, EndDate datetime)

INSERT INTO #HrShift ( Id,  ShiftName,       DaysOfWeek, StartTime,   EndTime,     StartDate,   EndDate) VALUES (1,   'Day Shift-1',     'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday' ,    '09:00 AM' ,   '06:00 PM',    '2016-01-01' , NULL)
INSERT INTO #HrShift ( Id,  ShiftName,       DaysOfWeek, StartTime,   EndTime,     StartDate,   EndDate) VALUES (2,  'Day Shift-2' ,  'Sunday,Monday,Tuesday,Wednesday,Thursday'   ,  '10:00 AM'   , '07:00 PM' ,   '2010-01-01' , NULL)
INSERT INTO #HrShift ( Id,  ShiftName,       DaysOfWeek, StartTime,   EndTime,     StartDate,   EndDate) VALUES (3,   'Day Shift-3' ,  'Sunday,Monday,Tuesday,Wednesday,Thursday' ,    '11:00 AM'   , '08:00 PM' ,   '2010-01-01' , NULL)

    CREATE TABLE #ShiftType (Id int,  Name varchar(50))


INSERT INTO #ShiftType(Id,  Name) VALUES (1,   'Primary')
INSERT INTO #ShiftType(Id,  Name) VALUES (2,   'Roster')

CREATE TABLE #EmployeeShifts (Id int,  EmpId int,   HrShiftId int,  ShiftTypeId int,    StartDate datetime,   EndDate datetime)


INSERT INTO #EmployeeShifts(Id,  EmpId,   HrShiftId,   ShiftTypeId,     StartDate,   EndDate ) VALUES(1,   1,       1,           1,               '2018-01-01',  NULL    )
INSERT INTO #EmployeeShifts(Id,  EmpId,   HrShiftId,   ShiftTypeId,     StartDate,   EndDate ) VALUES(2,   1,       2,           2,               '2018-02-01',  '2018-02-01')
INSERT INTO #EmployeeShifts(Id,  EmpId,   HrShiftId,   ShiftTypeId,     StartDate,   EndDate ) VALUES(3,   2,       1,           1,               '2018-01-01',  NULL)
INSERT INTO #EmployeeShifts(Id,  EmpId,   HrShiftId,   ShiftTypeId,     StartDate,   EndDate ) VALUES(4,   2,       2,           2,               '2018-02-01',  '2019-02-05')
INSERT INTO #EmployeeShifts(Id,  EmpId,   HrShiftId,   ShiftTypeId,     StartDate,   EndDate ) VALUES(5,   2,       3,           2,               '2018-02-01',  '2019-02-01')


    SELECT * FROM #Monthdaytable 
    --SELECT * FROM #HrShift
    --SELECT * FROM #ShiftType
    --SELECT * FROM #EmployeeShifts

这是您需要的查询:

SELECT m.DisplayDate ,EmpId,ShiftName,t.Name,StartTime,EndTime
        FROM #EmployeeShifts e INNER JOIN
                #ShiftType t ON  e.ShiftTypeId = t.Id INNER JOIN
                #HrShift s ON s.Id = e.HrShiftId INNER JOIN
                #Monthdaytable m ON 1 = 1
        WHERE CONVERT(varchar,m.Actualdate,112)>=CONVERT(varchar,e.StartDate,112)
                and  CONVERT(varchar,m.Actualdate,112)<=CONVERT(varchar,ISNULL(e.EndDate, m.Actualdate),112)            
                and s.DaysOfWeek  LIKE '%'+m.Week_Day_Name+'%' 

降低温度

    DROP TABLE #EmployeeShifts
    DROP TABLE #ShiftType
    DROP TABLE #HrShift
    DROP TABLE #Monthdaytable