SQL Server将日期范围作为列进行透视

时间:2014-03-18 14:49:03

标签: sql-server pivot pivot-table

我有一张表格,其中包含记录员工到达和分散时间的以下结构:

enter image description here

我希望在查询/存储过程中实现的是根据附加图像上的底部网格在日期范围之间返回的数据透视类型数据。

请问您的专业知识或样本如何完成?我一直在研究,但我所有的努力都没有结果。

2 个答案:

答案 0 :(得分:2)

您可以使用PIVOT函数获取最终结果,但由于您要汇总string / time值,因此您还需要使用像row_number()这样的窗函数来为每个userid / datein组合返回多行。

我会使用类似于以下内容的子查询来返回每个userid / datein组合的唯一序列号数据:

select name, 
    datein = convert(varchar(10), datein, 120), 
    dttime = cast(timein as varchar(5)) + ' - '+ cast(timeout as varchar(5)),
    row_number() over(partition by userid, datein order by datein) seq
from dbo.yourtable;

获得此数据后,您可以轻松应用数据透视:

select name, [2013-04-10]
from
(
    select name, 
        datein = convert(varchar(10), datein, 120), 
        dttime = cast(timein as varchar(5)) + ' - '+ cast(timeout as varchar(5)),
        row_number() over(partition by userid, datein order by datein) seq
    from dbo.yourtable
) d
pivot
(
    max(dttime)
    for datein in ([2013-04-10])
) piv;

然后,如果您有未知数量的值,那么您将需要使用动态SQL:

DECLARE 
    @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @startdate datetime,
    @enddate datetime,
    @paramdef nvarchar(max)

set @startdate = '2013-02-01'
set @enddate = '2013-05-10';
set @paramdef = '@startdate datetime, @enddate datetime';

select @cols = STUFF((SELECT ',' + QUOTENAME(convert(varchar(10), datein, 120)) 
                    from dbo.yourtable
                    where datein > @startdate
                        and datein <= @enddate
                    group by datein
                    order by datein
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = N'SELECT name, '+ @cols + '
            from 
            (
                select name, 
                    datein = convert(varchar(10), datein, 120), 
                    dttime = cast(timein as varchar(5)) + '' - ''+ cast(timeout as varchar(5)),
                    row_number() over(partition by userid, datein order by datein) seq
                from dbo.yourtable
                where datein > @startdate
                    and datein <= @enddate
            ) x
            pivot 
            (
                max(dttime)
                for datein in ('+@cols+')
            ) p '

exec sp_executesql @query, @paramdef, @startdate = @startdate, @enddate = @enddate;

答案 1 :(得分:-1)

我会在以下行添加DISTINCT:

select @cols - select @cols = stuff((select DISTINCT ',' + ....