我正在使用SQL Server 2008 R2。我在合并表时遇到问题。我们有500多名员工
我有以下表格:
Calendar
表 - 保留日期为1/1/2005至2016年12月31日Attendance
表 - 供员工出席LeaveHistory
表 - 用于休假历史LeaveBreakDown
table -for leave break down Holiday
表 - 假期我们的目标,日期范围从日历(2015年11月1日 - 2015年11月30日) 我们希望显示完整的日子,即使出勤率不等于总天数。
这是我的第一个解决方案,但速度太慢,没有日历表
FETCH NEXT FROM Employees INTO @EmployeeID,@BranchCode,@IsOfficer, @FirstName, @MiddleName, @LastName, @RankCode;
WHILE @@FETCH_STATUS = 0
BEGIN
WHILE @StartDate <= @EndDate
BEGIN
INSERT INTO #tblData(ActualDate,EmployeeID,BranchCode,IsOfficer, FirstName, MiddleName, LastName, RankCode, LeaveCode, Gender, ShiftCode,ShiftIn,ShiftOut,IsRestDay)
SELECT
@StartDate
, @EmployeeID
, @BranchCode
, @IsOfficer
, @FirstName
, @MiddleName
, @LastName
, @RankCode
, LB.LeaveBreakDownCode
, E.Gender
,ShiftCode = SS.ShiftCode
,ShiftIn = CONVERT(DATETIME, CONVERT(VARCHAR(20), DATEADD(day,0,@StartDate), 101) + ' ' + CONVERT(VARCHAR(20), SS.ShiftIn,108))
,ShiftOut = CASE
WHEN SS.ShiftOut < SS.ShiftIn THEN CONVERT(DATETIME, CONVERT(VARCHAR(20), DATEADD(day,1,@StartDate), 101) + ' ' + CONVERT(VARCHAR(20), SS.ShiftOut ,108))
ELSE CONVERT(DATETIME, CONVERT(VARCHAR(20), DATEADD(day,0,@StartDate), 101) + ' ' + CONVERT(VARCHAR(20), SS.ShiftOut ,108))
END
,IsRestDay = CASE
WHEN SS.Sunday = 1 AND DATEPART(weekday, @StartDate) = 1 THEN 1
WHEN SS.Monday = 1 AND DATEPART(weekday, @StartDate) = 2 THEN 1
WHEN SS.Tuesday = 1 AND DATEPART(weekday, @StartDate) = 3 THEN 1
WHEN SS.Wednesday = 1 AND DATEPART(weekday, @StartDate) = 4 THEN 1
WHEN SS.Thursday = 1 AND DATEPART(weekday, @StartDate) = 5 THEN 1
WHEN SS.Friday = 1 AND DATEPART(weekday, @StartDate) = 6 THEN 1
WHEN SS.Saturday = 1 AND DATEPART(weekday, @StartDate) = 7 THEN 1
ELSE 0
END
FROM Employees E
LEFT JOIN (
SELECT
LB.LeaveBreakDownCode
, LB.EmployeeID
FROM LeaveBreakDown LB
INNER JOIN LeaveHistory LH ON LH.LeaveHistoryCode = LB.LeaveHistoryCode AND LB.DateLeave = @StartDate AND LH.Status IN ('0','1')
WHERE LB.EmployeeID = @EmployeeID
) LB ON LB.EmployeeID = E.EmployeeID
LEFT JOIN ShiftSchedule SS ON SS.EmployeeID = E.EmployeeID AND @StartDate BETWEEN SS.EffectivityDate AND SS.EndDate
WHERE E.Status='1' AND E.ResignedDate IS NULL AND E.EmployeeID = @EmployeeID
SET @StartDate = DATEADD(day,1,@StartDate)
END
SET @StartDate = @InitialDate -- Reinitialize Start Date
FETCH NEXT FROM Employees INTO @EmployeeID, @BranchCode,@IsOfficer,@FirstName, @MiddleName, @LastName, @RankCode;
END;
关闭员工; DEALLOCATE员工;
使用此解决方案,如果我们要运行脚本。花了3分钟,有时是6分钟。
可能是结构
日期(&#39; 11/1 / 2015&#39; - &#39; 11/30/2015&#39;) - &GT;勤 - &GT; LeaveHistory
日期范围中日期表的所有日期都将填入来自不同表格的值。
答案 0 :(得分:0)
递归CTE样本。你可以用更少的表和列来实现你的例子然后逐渐增加。
DECLARE @StartDate DATETIME = '11/1/2015'
DECLARE @EndDate DATETIME = '11/30/2015';
WITH CTE
AS (
SELECT @StartDate DT
UNION ALL
SELECT DATEADD(day, 1, DT)
FROM CTE
WHERE DT < @EndDate
)
SELECT *
FROM CTE