Динамическая сводная таблица с 3 столбцами - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь использовать динамический свод, чтобы столбец с датами был именами столбцов.

Я хочу, чтобы эта таблица:

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 голосов
/ 30 мая 2018

Использование динамического 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

0 голосов
/ 30 мая 2018

Попробуйте:

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 )
...