SQL Server 2008 数据透视表查询 - 日期时间

SQL Server 2008 Pivot Query - Datetime

我有多行员工的时间 in/out 的记录,如何查询具有相同 ID、名称但不同时间 in/out 的数据透视表?

如下图所示:

您可以像这样使用旋转:

;WITH dtrTable AS (  --just a test sample of your table
SELECT *
FROM (VALUES
(1, 'emp1', '2016-10-20', '2016-10-20 10:00:00.000', '2016-10-20 15:00:00.000'),
(1, 'emp1', '2016-10-20', '2016-10-20 15:30:00.000', '2016-10-20 17:00:00.000'),
(1, 'emp1', '2016-10-20', '2016-10-20 18:30:00.000', '2016-10-20 19:00:00.000'),
(2, 'emp2', '2016-10-20', '2016-10-20 10:00:00.000', '2016-10-20 19:00:00.000'),
(2, 'emp2', '2016-10-20', '2016-10-20 21:00:00.000', '2016-10-20 22:00:00.000'),
(2, 'emp2', '2016-10-21', '2016-10-20 11:00:00.000', '2016-10-20 21:00:00.000')
) as t(empId, empName, dtrDate, dtrIn, dtrOut)
)

SELECT *
FROM (
    SELECT  empId, 
            empName, 
            dtrDate,
            [Columns]+seq as [Columns],
            [Values]
    FROM (
        SELECT *,
                CAST(ROW_NUMBER() OVER (PARTITION BY empId, dtrDate ORDER BY dtrIn) as nvarchar(100)) as seq
        FROM dtrTable
    ) as t
    UNPIVOT (
        [Values] FOR [Columns] IN ([dtrIn],[dtrOut])
    ) as unpvt
) as d
PIVOT (
    MAX([Values]) FOR [Columns] IN ([dtrIn1],[dtrOut1],[dtrIn2],[dtrOut2],[dtrIn3],[dtrOut3])
) as pvt

输出:

empId   empName dtrDate     dtrIn1                  dtrOut1                 dtrIn2                  dtrOut2                 dtrIn3                  dtrOut3
1       emp1    2016-10-20  2016-10-20 10:00:00.000 2016-10-20 15:00:00.000 2016-10-20 15:30:00.000 2016-10-20 17:00:00.000 2016-10-20 18:30:00.000 2016-10-20 19:00:00.000
2       emp2    2016-10-20  2016-10-20 10:00:00.000 2016-10-20 19:00:00.000 2016-10-20 21:00:00.000 2016-10-20 22:00:00.000 NULL                    NULL
2       emp2    2016-10-21  2016-10-20 11:00:00.000 2016-10-20 21:00:00.000 NULL                    NULL                    NULL                    NULL    

Unpivot 部分会给你这个 table:

empId   empName dtrDate     Columns Values
1       emp1    2016-10-20  dtrIn1  2016-10-20 10:00:00.000
1       emp1    2016-10-20  dtrOut1 2016-10-20 15:00:00.000
1       emp1    2016-10-20  dtrIn2  2016-10-20 15:30:00.000
1       emp1    2016-10-20  dtrOut2 2016-10-20 17:00:00.000
1       emp1    2016-10-20  dtrIn3  2016-10-20 18:30:00.000
1       emp1    2016-10-20  dtrOut3 2016-10-20 19:00:00.000
2       emp2    2016-10-20  dtrIn1  2016-10-20 10:00:00.000
2       emp2    2016-10-20  dtrOut1 2016-10-20 19:00:00.000
2       emp2    2016-10-20  dtrIn2  2016-10-20 21:00:00.000
2       emp2    2016-10-20  dtrOut2 2016-10-20 22:00:00.000
2       emp2    2016-10-21  dtrIn1  2016-10-20 11:00:00.000
2       emp2    2016-10-21  dtrOut1 2016-10-20 21:00:00.000

这里我使用 ROW_NUMBER() 和分区来对 来龙去脉 进行排序。 ROW_NUMBER() 生成的数字也有助于创建列,我们不能在数据透视部分使用相同的列名。