(Расширенные исходные данные для иллюстрации использования порядкового номера)
Эта проблема намного проще, если вы нормализуете структуру.Поскольку вы пытаетесь сделать арифметику для столбцов, они должны быть строками, а не столбцами.
Declare @X_Table Table
(
Id int not null Identity(1,1) Primary Key
, x1 float not null
, x2 float not null
, x3 float not null
, x4 float not null
, x5 float not null
, x111 float not null
, x112 float not null
, x113 float not null
, x114 float not null
, x115 float not null
, x11 float not null
, x12 float not null
, x13 float not null
, x14 float not null
, x15 float not null
)
Insert @X_Table( x1, x2, x3, x4, x5
, x111, x112, x113, x114, x115
, x11, x12, x13, x14, x15
)
Select 438, 498, 3625, 3645, 5000, 438, 498, 3625, 3645, 5000, 438, 498, 3625, 3645, 5000
Union All Select 438, 498, 3625, 3648, 5000, 438, 498, 3625, 3648, 5000, 438, 498, 3625, 3648, 5000
Union All Select 438, 498, 3625, 3629, 5000, 438, 498, 3625, 3629, 5000, 438, 498, 3625, 3629, 5000
Union All Select 437, 501, 3625, 3626, 5000, 437, 501, 3625, 3626, 5000, 437, 501, 3625, 3626, 5000
Union All Select 438, 498, 3626, 3629, 5000, 438, 498, 3626, 3629, 5000, 438, 498, 3626, 3629, 5000
Union All Select 439, 498, 3626, 3629, 5000, 439, 498, 3626, 3629, 5000, 439, 498, 3626, 3629, 5000
Union All Select 440, 5000, 3627, 3628, 5000, 440, 5000, 3627, 3628, 5000, 440, 5000, 3627, 3628, 5000
Union All Select 444, 5021, 3631, 3634, 5000, 444, 5021, 3631, 3634, 5000, 444, 5021, 3631, 3634, 5000
Union All Select 451, 5025, 3635, 3639, 5000, 451, 5025, 3635, 3639, 5000, 451, 5025, 3635, 3639, 5000
Union All Select 458, 5022, 3640, 3644, 5000, 458, 5022, 3640, 3644, 5000, 458, 5022, 3640, 3644, 5000
Union All Select 465, 525, 3646, 3670, 5000, 465, 525, 3646, 3670, 5000, 465, 525, 3646, 3670, 5000
Union All Select 473, 533, 3652, 3676, 5000, 473, 533, 3652, 3676, 5000, 473, 533, 3652, 3676, 5000
Union All Select 481, 544, 3658, 3678, 5000, 481, 544, 3658, 3678, 5000, 481, 544, 3658, 3678, 5000
Union All Select 484, 544, 3661, 3665, 5000, 484, 544, 3661, 3665, 5000, 484, 544, 3661, 3665, 5000
Union All Select 484, 532, 3669, 3662, 2945, 484, 532, 3669, 3662, 2945, 484, 532, 3669, 3662, 2945
Union All Select 482, 520, 3685, 3664, 2952, 482, 520, 3685, 3664, 2952, 482, 520, 3685, 3664, 2952
Union All Select 481, 522, 3682, 3661, 2955, 481, 522, 3682, 3661, 2955, 481, 522, 3682, 3661, 2955
Union All Select 480, 525, 3694, 3664, 2948, 480, 525, 3694, 3664, 2948, 480, 525, 3694, 3664, 2948
Union All Select 481, 515, 5018, 3664, 2956, 481, 515, 5018, 3664, 2956, 481, 515, 5018, 3664, 2956
Union All Select 479, 5000, 3696, 3661, 2953, 479, 5000, 3696, 3661, 2953, 479, 5000, 3696, 3661, 2953
Следующая таблица явно статична.Однако, если вы собираетесь использовать динамический SQL (который не рекомендуется в T-SQL, но, очевидно, выполнимый), заполнение этой следующей таблицы будет единственной частью.
Declare @X_Table_Normalized Table
(
Id int not null
, Ordinal int not null
, Name varchar(10) not null
, Value float not null
)
Insert @X_Table_Normalized( Id, Ordinal, Name, Value )
Select Id, 1, 'x1', x1 From @X_Table
Union All Select Id, 2, 'x2', x2 From @X_Table
Union All Select Id, 3, 'x3', x3 From @X_Table
Union All Select Id, 4, 'x4', x4 From @X_Table
Union All Select Id, 5, 'x5', x5 From @X_Table
Union All Select Id, 6, 'x111', x111 From @X_Table
Union All Select Id, 7, 'x112', x112 From @X_Table
Union All Select Id, 8, 'x113', x113 From @X_Table
Union All Select Id, 9, 'x114', x114 From @X_Table
Union All Select Id, 10, 'x115', x115 From @X_Table
Union All Select Id, 11, 'x11', x11 From @X_Table
Union All Select Id, 12, 'x12', x12 From @X_Table
Union All Select Id, 13, 'x13', x13 From @X_Table
Union All Select Id, 14, 'x14', x14 From @X_Table
Union All Select Id, 15, 'x15', x15 From @X_Table
Таблица 1 - Сумма по(оригинал) столбец
Declare @Table1 Table
(
Id int not null
, Name varchar(25) not null
, Ordinal int not null
, Value float not null
)
Insert @Table1( Id, Name, Ordinal, Value )
Select Row_Number() Over( Order By Ordinal, Name )
, Name, Ordinal, Sum(Value)
From @X_Table_Normalized
Group By Ordinal, Name
Таблица 2 - Суммы продуктов по (оригиналу) столбец
Declare @Table2 Table
(
Id int not null
, Name varchar(25) not null
, Ordinal int not null
, Value float not null
)
Insert @Table2( Id, Name, Ordinal, Value )
Select Row_Number() Over ( Order By T1.Ordinal, T1.Name, T2.Ordinal, T2.Name ) As Id
, 'Sum(' + T1.Name + '*' + T2.Name + ')' As Name
, T1.Ordinal + 100 * T2.Ordinal
, Sum( T1.Value * T2.Value ) As Value
From @X_Table_Normalized As T1
Join @X_Table_Normalized As T2
On T2.Id = T1.Id
Where T1.Ordinal <= T2.Ordinal
Group By T1.Name, T1.Ordinal, T2.Name, T2.Ordinal
Таблица 3 - Суммы продуктов по диагонали по (оригиналу) столбцу
Declare @Table3 Table
(
Id int not null
, Name varchar(25) not null
, Ordinal int not null
, Value float not null
)
Insert @Table3( Id, Name, Ordinal, Value )
Select Row_Number() Over ( Order By T1.Ordinal, T1.Name, T2.Ordinal, T2.Name ) As Id
, 'Sum(' + T1.Name + '*' + T2.Name + ')' As Name
, T1.Ordinal + 100 * T2.Ordinal
, Sum( T1.Value * T2.Value ) As Value
From @X_Table_Normalized As T1
Join @X_Table_Normalized As T2
On T2.Id = T1.Id
Where T1.Ordinal = T2.Ordinal
Group By T1.Name, T1.Ordinal, T2.Name, T2.Ordinal
Select * From @Table1 Order By Ordinal
Select * From @Table2 Order By Ordinal
Select * From @Table3 Order By Ordinal
Заполнение нормализованной таблицы динамическим SQL
В зависимости от того, как это используется, вы можете инкапсулировать заполнение нормализованной таблицы с использованием динамического SQL.Если вы это сделаете, вам нужно будет использовать реальные таблицы или временные таблицы в отличие от временных переменных.Этот код может выглядеть примерно так:
Declare @Sql nvarchar(max)
Set @Sql = 'Insert #X_Table_Normalized_Dynamic( Id, Ordinal, Name, Value )|'
Select @Sql = @Sql + ' Union All Select Id'
+ ', ' + Cast( Row_Number() Over ( Order By ORDINAL_POSITION ) As varchar(10) )
+ ', ' + QuoteName(COLUMN_NAME, '''')
+ ', ' + QuoteName(COLUMN_NAME)
From INFORMATION_SCHEMA.COLUMNS
Where TABLE_NAME = 'MySourceTable'
Set @Sql = Replace( @Sql, '| Union All ', ' ')
Exec( @Sql )