【问题标题】:Dynamic pivot a 3 column table动态透视 3 列表
【发布时间】:2018-05-30 11:39:15
【问题描述】:

我正在尝试使用动态透视来将包含日期的列作为列名。

我想要这张桌子:

App     Date         Count
Excel   2018-05-01   1
Excel   2018-05-02   1
Excel   2018-05-03   2
Word    2018-05-02   3
Word    2018-05-07   5
Word    2018-05-12   2
Paint   2018-05-07   6

看起来像这样:

       2018-05-01  2018-05-02  2018-05-03  2018-05-07  2018-05-12
Excel  1           1           2           0           0
Word   0           3           0           5           2
Paint  0           0           0           6           0

我不能使用正常的枢轴,因为我不知道实际日期是多少或日期。每个应用程序可以有不同的行数。此表也不只是 SELECT * FROM TABLE,它由子查询和 CTE 组成,因此使用起来有点复杂。

感谢任何帮助。如果您需要更多信息,请告诉我。

【问题讨论】:

    标签: sql sql-server tsql pivot common-table-expression


    【解决方案1】:

    使用动态 TSQL:

    if OBJECT_ID('dbo.test') is null
        create table dbo.test(App varchar(50), [Date]  varchar(50), [Count] int)
    
    truncate table  dbo.test 
    
    insert into dbo.test   values
    ('Excel',   '2018-05-01',   1),
    ('Excel',   '2018-05-02',   1),
    ('Excel',   '2018-05-03',   2),
    ('Word ',   '2018-05-02',   3),
    ('Word ',   '2018-05-07',   5),
    ('Word ',   '2018-05-12',   2),
    ('Paint',   '2018-05-07',   6)
    
    declare @dates nvarchar(max)='' --holds all the dates that will become column names 
    declare @dates_aliases nvarchar(max)='' --holds the headers without NULL values
    declare @sql nvarchar(max)='' --contains the TSQL dinamically generated 
    
    select @dates = @dates + ', [' + CONVERT(char(10), [date],126)+ ']' from dbo.test  
                    group by [date]
    select @dates_aliases = @dates_aliases + ', isnull([' 
                           + CONVERT(char(10), [date],126)+ '], 0) as [' 
                           + CONVERT(char(10), [date],126)+ ']' 
    from dbo.test  group by [date]
    set @dates = RIGHT(@dates, len(@dates)-2) 
    set @dates_aliases = RIGHT(@dates_aliases, len(@dates_aliases)-2) 
    
    set @sql = @sql + ' select piv.[App], ' + @dates_aliases
    set @sql = @sql + ' from '
    set @sql = @sql + ' ( '
    set @sql = @sql + ' select [App], [Date], [Count] '
    set @sql = @sql + ' from dbo.test   '
    set @sql = @sql + ' ) src '
    set @sql = @sql + ' pivot '
    set @sql = @sql + ' ( '
    set @sql = @sql + ' max([Count]) '
    set @sql = @sql + ' for [Date] in ('+@dates+') '
    set @sql = @sql + ' ) piv '
    
    exec(@sql)
    

    结果:

    【讨论】:

      【解决方案2】:

      试试这个:

      SELECT A.* 
      INTO #TEMP
      FROM
      (
      
      SELECT 'Excel' as  app,'2018-05-01' as 'Date',1 as 'Count'
      UNION ALL
      SELECT 'Excel' as  app,'2018-05-02' as 'Date',1 as 'Count'
      UNION ALL
      SELECT 'Excel' as  app,'2018-05-03' as 'Date',2 as 'Count'
      UNION ALL
      SELECT 'Word' as  app,'2018-05-02' as 'Date', 3 as 'Count'
      UNION ALL
      SELECT 'Word' as  app,'2018-05-07' as 'Date', 5 as 'Count'
      UNION ALL
      SELECT 'Word' as  app,'2018-05-12' as 'Date', 2 as 'Count'
      UNION ALL
      SELECT 'Paint' as  app,'2018-05-07' as 'Date', 6 as 'Count'
      
      ) as A
      

      回答:

      DECLARE @SQL VARCHAR(MAX)
      DECLARE @Columns VARCHAR(MAX) = ''
      DECLARE @Columns2 VARCHAR(MAX) = ''
      
      SELECT @Columns = @Columns + '[' + a.[Column] + '], '
      FROM
      (SELECT DISTINCT [date] as [Column]
      FROM #TEMP) as a
      
      SELECT @Columns2 = @Columns2 + 'ISNULL([' + a.[Column] + '],0) as [' + a.[column] +'], '
      FROM
      (
      SELECT DISTINCT [date] as [Column]
      FROM #TEMP
      ) as a
      
      SET @Columns2 = Left(@Columns2, Len(@Columns2) - 1)
      SET @Columns = Left(@Columns, Len(@Columns) - 1)
      
      SET @SQL = 'SELECT app, ' + @Columns2
      + ' FROM #TEMP PIVOT (Avg (Count) FOR Date IN ('
      + @Columns
      + ')) AS pt '
      --PRINT @Columns
      EXEC( @SQL )
      

      【讨论】:

      • 我无法创建这样的临时表,因为我不知道值是什么。使用 word 和 excel 只是一个例子。我尝试使用 CTE,但我只能从中调用一次,因此在这种情况下无法使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 2023-03-14
      • 2019-12-22
      相关资源
      最近更新 更多