Транспонировать столбцы и строки динамически - PullRequest
0 голосов
/ 30 апреля 2018

Я пытался использовать информацию из похожей темы, но все еще не могу с ней справиться.

У меня есть данные примерно так:

+------------+--------------+--------+--------+------------+
|    date    | business_day | total  | number | number_2   |
+------------+--------------+--------+--------+------------+
| 2018-04-03 |            1 | 325857 |      0 |      888   |
| 2018-04-04 |            2 | 196308 |      2 |      829   |
| 2018-04-05 |            3 | 434970 |      1 |      661   |
| 2018-04-06 |            4 | 665941 |      1 |     1135   |
| 2018-04-09 |            5 | 589334 |      0 |      837   |
+------------+--------------+--------+--------+------------+  

Как я могу транспонировать его, когда число строк может быть динамическим (в этом случае столбцов нет), конечный результат должен быть таким:

+--------------+------------+------------+------------+------------+--------------+
|     date     | 2018-04-03 | 2018-04-04 | 2018-04-05 | 2018-04-06 | 2018-04-09   |
+--------------+------------+------------+------------+------------+--------------+
| business_day |          1 |          2 |          3 |          4 |          5   |
| total        |     325857 |     196308 |     434970 |     665941 |     589334   |
| number       |          0 |          2 |          1 |          1 |          0   |
| number_2     |        888 |        829 |        661 |       1135 |        837   |
+--------------+------------+------------+------------+------------+--------------+

Не могли бы вы мне помочь, пожалуйста?

1 Ответ

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

Если вам нужен динамический запрос, который автоматически создает все столбцы для всех значений Date, вы можете использовать динамический SQL, но помните о проблемах безопасности (внедрение SQL и т. Д.) Этого подхода!

Вот пример сценария, который динамически генерирует запрос со всеми столбцами для вашего Date:

if OBJECT_ID('Test') is not null
    drop table [dbo].[Test]

CREATE TABLE [dbo].[Test]([date] datetime, business_day int, total int, number int, number_2 int) 

insert into [dbo].[Test] select '2018-04-03', 1, 325857, 0, 888 
insert into [dbo].[Test] select '2018-04-04', 2, 196308, 2, 829 
insert into [dbo].[Test] select '2018-04-05', 3, 434970, 1, 661 
insert into [dbo].[Test] select '2018-04-06', 4, 665941, 1, 1135 
insert into [dbo].[Test] select '2018-04-09', 5, 589334, 0, 837 

declare @dates nvarchar(max)='' --this variable holds all the dates that will become column names
declare @sql nvarchar(max)=''   --this variable contains the TSQL dinamically generated

select @dates = @dates +  ', [' + CONVERT(char(10), [date],126)+  ']' from [dbo].[Test] 
set @dates = RIGHT(@dates, len(@dates)-2)

set @sql = @sql + 'select col as [date], ' + @dates
set @sql = @sql + 'from '
set @sql = @sql + '( '
set @sql = @sql + ' select [date] , col,val,ord '
set @sql = @sql + ' from [dbo].[Test] '
set @sql = @sql + ' CROSS APPLY ('
set @sql = @sql + '     VALUES (''business_day'',business_day, 1), '
set @sql = @sql + '            (''total'',total, 2), '
set @sql = @sql + '            (''number'',number, 3), '
set @sql = @sql + '            (''number_2'',number_2, 4) '
set @sql = @sql + ' )CS (COL,VAL,ORD) '
set @sql = @sql + ') src '
set @sql = @sql + 'pivot ( max(val) for [Date] in (' + @dates + ') ) piv '
set @sql = @sql + 'order by ord'

exec(@sql)

Вот результат этого утверждения:

enter image description here

...