动态转动3列表

时间:2018-05-30 11:39:16

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

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

我想要这张桌子:

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组成,因此使用起来有点复杂。

感谢任何帮助。如果您需要更多信息,请与我们联系。

2 个答案:

答案 0 :(得分:1)

试试这个:

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 )

答案 1 :(得分: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)

结果:

enter image description here