VB.net SQL数据透视表

VB.net SQL数据透视表,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有两列需要按日期返回用户名计数 DateOnly Username 12/01/2014 00:00:00 Dave 12/01/2014 00:00:00 Bob 12/01/2014 00:00:00 Steve 12/01/2014 00:00:00 Richard 13/01/2014 00:00:00 Dave 13/01/2014 00:00:00 Dave 13/01/2014 00:00:00 B

我有两列需要按日期返回用户名计数

DateOnly              Username
 12/01/2014 00:00:00    Dave
 12/01/2014 00:00:00    Bob
 12/01/2014 00:00:00    Steve
 12/01/2014 00:00:00    Richard
 13/01/2014 00:00:00    Dave
 13/01/2014 00:00:00    Dave
 13/01/2014 00:00:00    Bob
 14/01/2014 00:00:00    Dave
以此类推,每天将始终有大约2000-3000条记录

我想把它展示得像

Username          12/01/2014            13/01/2014         14/01/2014
Dave                 1                       2                 1
Bob                  1                       1                 0
Steve                1                       0                 0
Richard              1                       0                 0
我希望用户选择两个日期进行搜索,即
WHERE=12/01/2014和14/01/2014

所以我不知道会有多少列


有人能帮我解决这个问题吗?

我的建议是,首先使用有限的日期编写查询,这样您就可以获得正确的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版本将是:

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;
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;
| 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 |