我尝试设置查询以提取员工任期报告。我有一个员工状态表,用于跟踪每个员工的信息(例如 - 雇用日期,期限日期,工资变更等)。表格如下所示:
EmployeeID | Date | Event
1 | 1/1/99 | 1
2 | 1/2/99 | 1
1 | 1/3/99 | 2
1 | 1/4/99 | 1
我使用数据透视表将表格从垂直布局移动到水平布局
SELECT [FK_EmployeeID], MAX([1]) AS [Hire Date], ISNULL(MAX([2]), DATEADD(d, 1, GETDATE())) AS [Term Date]
FROM DT_EmployeeStatusEvents PIVOT (MAX([Date]) FOR [EventType] IN ([1], [2])) T
GROUP BY [FK_EmployeeID]
我得到这样的结果:
EmployeeID | 1 | 2
1 | 1/4/99 | 1/3/99
2 | 1/2/99 | *null*
但是,我遇到的问题是我需要为每个员工设置两组值。 (我们雇用了很多经常性的季节性)我想要的是一种将列转换为行的方法,为每个员工选择雇用日期(1)和下一个期限日期(2),如下所示:
EmployeeID | 1 | 2
1 | 1/1/99 | 1/3/99
2 | 1/2/99 | *null*
1 | 1/4/99 | *null*
这可能吗?我已经查看了很多PIVOT示例,它们都显示了一个聚合函数。
答案 0 :(得分:1)
问题是您试图转动datetime
值,因此您只能使用max
或min
作为聚合函数。当您使用这些时,每个employeeid
只会返回一行。
为了解决这个问题,您需要在数据分组过程中使用一些值 - 我建议使用像row_number()
这样的窗口函数。您可以创建子查询:
select employeeid, date, event
, row_number() over(partition by employeeid, event
order by date) seq
from DT_EmployeeStatusEvents
见SQL Fiddle with Demo。这会为每个employeeId
和event
组合创建唯一值。然后将这个新数字分组,以便您可以返回多行。您完整的查询将是:
select employeeid, [1], [2]
from
(
select employeeid, date, event
, row_number() over(partition by employeeid, event
order by date) seq
from DT_EmployeeStatusEvents
) d
pivot
(
max(date)
for event in ([1], [2])
) piv
order by employeeid;
答案 1 :(得分:0)
这应该让你开始......
DECLARE @EMP TABLE (EMPID INT, dDATE DATETIME, EVENTTYPE INT)
INSERT INTO @EMP
SELECT 1,'1/1/99',1 UNION ALL
SELECT 2,'1/2/99',1 UNION ALL
SELECT 1,'1/3/99',2 UNION ALL
SELECT 1,'1/4/99',1
SELECT EMPID, HIRE, TERM
FROM (SELECT EMPID, dDATE, 'HIRE' AS X, ROW_NUMBER() OVER(PARTITION BY EMPID, EVENTTYPE ORDER BY DDATE) AS INSTANCE FROM @EMP WHERE EVENTTYPE=1
UNION ALL
SELECT EMPID, dDATE, 'TERM' AS X, ROW_NUMBER() OVER(PARTITION BY EMPID, EVENTTYPE ORDER BY DDATE) AS INSTANCE FROM @EMP WHERE EVENTTYPE=2) DATATABLE
PIVOT (MIN([DDATE])
FOR X IN ([HIRE],[TERM])) PIVOTTABLE