如何将员工的注意力从行转换为列

时间:2017-07-06 13:24:49

标签: sql-server sql-server-2008

我有两个表,比方说,tblEmployees和tblAttendence。员工表仅包含员工代码和名称,并且关注表包含每个员工每天的条目(如果不存在或不存在)。

我发布了这个问题的测试脚本,其中包含员工的5个虚拟记录和每个员工在一个月(2017年6月)的参与表中的30行,因此参与表将总共有150(5x30)行。我需要以表格形式显示输出,显示每行中的员工姓名,但每一天都会显示在单独的列中。在我的测试脚本中,我使用左外连接到不同日期条件的同一个表只做了7天。

这是脚本:

----create dummy tables for 'Employee', and 'Attendence'
declare @tblEmployee table(
EmployeeID int,
EmployeeCode varchar(10),
EmployeeName varchar(255)
)

declare @tblAttendence table(
AttendenceID int identity(1, 1),
EmployeeID int,

AttendenceDate date,
AttendenceDay int,

Absence int
)


-----insert dummy records in both tables
declare @EmployeeID int = 1
declare @EmployeeCode varchar(10) 
declare @EmployeeName varchar(255) 

declare @CountEmployee int = 1
declare @CountDays int = 1


declare @UserYear int = 2017
declare @UserMonth int = 5

declare @DateFirst date = '1 jun 2017'
declare @DateLast date = '30 jun 2017'

declare @DateCurrent date = @DateFirst

while @CountEmployee <= 5
begin

    set @EmployeeID = @CountEmployee  
    set @EmployeeCode = ('E00' + CAST(@CountEmployee as varchar(10)))
    set @EmployeeName = ('Emp_Name_' + CAST(@CountEmployee as varchar(10))) 

    insert into @tblEmployee(
        EmployeeCode ,
        EmployeeID ,
        EmployeeName
        )   

    select 
        @EmployeeCode as EmployeeCode ,
        @EmployeeID  as EmployeeID ,
        @EmployeeName as EmployeeName;


    set @DateCurrent = @DateFirst
    set @CountDays = 1

    while @DateCurrent <= @DateLast
    begin

        insert into @tblAttendence(
            EmployeeID ,

            AttendenceDate ,
            AttendenceDay,
            Absence 
            )   

            select 
            @EmployeeID  as EmployeeID ,

            @DateCurrent as AttendenceDate ,
            day(@DateCurrent) as AttendenceDay,
            CAST(ROUND(RAND(),0) AS BIT) as Absence 

            set @DateCurrent = DATEADD(day, @CountDays, @DateFirst)
            set @CountDays = @CountDays + 1

    end

    set @CountEmployee = @CountEmployee + 1

end

-------at this points, we have 2 tables, 
-------tblEmployee contains 5 dummy records


----this query will do the actual job
----i.e, tranform attendence data against each employee for each day


select 
e.* 
,t1.Absence as Day1
,t2.Absence as Day2
,t3.Absence as Day3
,t4.Absence as Day4
,t5.Absence as Day5
,t6.Absence as Day6
,t7.Absence as Day7

from @tblEmployee e
left outer join @tblAttendence t1 on t1.EmployeeID = e.EmployeeID and t1.AttendenceDay = 1
left outer join @tblAttendence t2 on t2.EmployeeID = e.EmployeeID and t2.AttendenceDay = 2
left outer join @tblAttendence t3 on t3.EmployeeID = e.EmployeeID and t3.AttendenceDay = 3
left outer join @tblAttendence t4 on t4.EmployeeID = e.EmployeeID and t4.AttendenceDay = 4
left outer join @tblAttendence t5 on t5.EmployeeID = e.EmployeeID and t5.AttendenceDay = 5
left outer join @tblAttendence t6 on t6.EmployeeID = e.EmployeeID and t6.AttendenceDay = 6
left outer join @tblAttendence t7 on t7.EmployeeID = e.EmployeeID and t7.AttendenceDay = 7

现在我必须用完整的月份做相同的工作,这意味着需要30个列来反对员工记录,并且使用这种技术我必须复制粘贴相同的代码。

这是解决此问题的正确方法还是有更好的解决方案?

2 个答案:

答案 0 :(得分:0)

虽然您可以多次重复表连接,但使用如下所示的旋转技术可以在一个月的30/31天内获得所需的输出

希望有所帮助

select e.*,dc.*
from @tblEmployee e
left join (select EmployeeID,[1] as Day1, [2] as Day2, [3] as Day3, [4] as 
Day4, [5] as Day5,   
                         [6] as Day6, [7] as Day7, [8] as Day8, [9] as Day9, [10] as Day10, 
                         [11] as Day11, [12] as Day12, [13] as Day13, [14] as Day14, [15] as Day15, 
                         [16] as Day16, [17] as Day17, [18] as Day18, [19] as Day19, [20] as Day20, 
                         [21] as Day21,[22] as Day22,[23] as Day23,[24] as Day24,[25] as Day25,[26] as Day26,
                         [27] as Day27,[28] as Day28,[29] as Day29,[30] as Day30,[31] as Day31
                from (select EmployeeID,Absence,AttendenceDay
                      from   @tblAttendence) d
                      pivot (max(Absence)
                              for AttendenceDay  in ([1], [2], [3], [4], [5], 
                                                    [6], [7], [8], [9], [10],
                                                    [11], [12], [13], [14], [15], 
                                                    [16], [17], [18], [19], [20],
                                                    [21], [22], [23], [24], [25],
                                                    [26], [27], [28], [29], [30],[31])) as pvt) as dc
 on dc.EmployeeId = e.EmployeeId 

答案 1 :(得分:0)

只需运行此cte,我们将在消息中获取查询然后复制并运行代码以及您将获得预期的结果

UICollectionView

这里还有一个方法是动态sql进程

DECLARE @SQL nvarchar(max)
;With cte
AS
(
SELECT ROW_NUMBER()OVER(Order by (SELECT 1)) AS Rno
FROM master..spt_values

)
,Ct2 AS
(
SELECT Rno FROM cte WHERE Rno <=30
)
SELECT DISTINCT  @SQL=CONCAT('SELECT e.*,',
STUFF((SELECT ', '+' t'+CAST(Rno AS VARCHAR(10))+'.Absence AS [Day'+CAST(Rno AS VARCHAR(10))+']' FROM Ct2 i
  FOR XML PATH ('')),1,1,''),'  FROM @tblEmployee e',
  STUFF((SELECT '  '+' LEFT OUTER JOIN @tblAttendence t'+CAST(Rno AS VARCHAR(10))+' ON t'+CAST(Rno AS VARCHAR(10))+'.EmployeeID = e.EmployeeID AND t'+CAST(Rno AS VARCHAR(10))+'.AttendenceDay ='+CAST(Rno AS VARCHAR(10)) FROM Ct2 i
  FOR XML PATH ('')),1,1,''))
FROM Ct2 o

PRINT @SQL