您可以使用 PIVOT 函数来获得最终结果,但是由于您正在聚合 string/time 值,因此您还需要使用像 row_number() 这样的窗口函数来为每个 @ 返回多行987654324@/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;