我的建议是首先用有限数量的日期编写查询,以便您可以获得适用于PIVOT查询的逻辑。
当你有值的数量有限,那么你可以很容易地硬编码查询:
select username,
[2014-01-12], [2014-01-13], [2014-01-14]
from
(
select username, dateonly
from yourtable
where dateonly >= '2014-01-12'
and dateonly <= '2014-01-14'
) d
pivot
(
count(dateonly)
for dateonly in ([2014-01-12], [2014-01-13], [2014-01-14])
) piv;
见SQL Fiddle with Demo。
一旦你有逻辑关闭,那么你可以创建一个动态SQL版本的查询。由于您将有未知的日期,因此我会创建一个日历表,其中包含将用于创建最终列值的日期。
例如,您可以创建类似表:
create table dates
(
dt datetime
);
insert into dates
values
('2014-01-01'), ('2014-01-02'), ('2014-01-03'),
('2014-01-04'), ('2014-01-05'), ('2014-01-06'),
('2014-01-07'), ('2014-01-08'), ('2014-01-09'),
('2014-01-10'), ('2014-01-11'), ('2014-01-12'),
('2014-01-13'), ('2014-01-14'), ('2014-01-15');
那么这个表将被用来创建动态列。其动态SQL版本将为:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startdate datetime,
@enddate datetime
DECLARE @ParmDefinition nvarchar(500)
SET @ParmDefinition = N'@startdt datetime, @enddt datetime'
-- these values would be passed into your stored procedure
set @startdate = '2014-01-10'
set @enddate = '2014-01-14'
-- this creates the list of final columns to be displayed using the
-- dates table. Using the calendar table makes sure that you return all dates you
-- requested even if you do not have those values in DateOnly
select @cols = STUFF((SELECT ',' + QUOTENAME(convert(varchar(10), dt, 120))
from dates
where dt >= @startdate
and dt <= @enddate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT username, ' + @cols + '
from
(
select username, dateonly
from yourtable
where dateonly >= @startdt
and dateonly <= @enddt
) x
pivot
(
count(dateonly)
for dateonly in (' + @cols + ')
) p '
execute sp_executesql @query,
@ParmDefinition,
@startdt = @startdate,
@enddt = @enddate;
请参阅SQL Fiddle with Demo。两个版本都给出了结果:
| USERNAME | 2014-01-10 | 2014-01-11 | 2014-01-12 | 2014-01-13 | 2014-01-14 |
|----------|------------|------------|------------|------------|------------|
| Bob | 0 | 0 | 1 | 1 | 0 |
| Dave | 0 | 0 | 1 | 2 | 1 |
| Richard | 0 | 0 | 1 | 0 | 0 |
| Steve | 0 | 0 | 1 | 0 | 0 |