Ini membutuhkan sejumlah teknik yang agak canggih yang digabungkan untuk melakukan ini. Masalah pertama adalah Anda memiliki data yang dibatasi. Ini melanggar 1NF ketika Anda menjejalkan beberapa nilai ke dalam satu sel. Bagian kedua dari teka-teki adalah bagaimana PIVOT data ini menjadi sejumlah kolom yang dinamis. Kebanyakan orang di sekitar SO lebih suka menggunakan PIVOT dinamis. Saya lebih suka menggunakan tab silang dinamis sebagai gantinya. Saya menemukan sintaksnya kurang tumpul dan bahkan sedikit lebih berkinerja daripada tab silang dinamis.
Anda dapat membaca tentang splitter yang biasanya saya gunakan di sini. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Keuntungan utama yang ditawarkan pembagi ini yang tidak dimiliki kebanyakan orang lain adalah ia mengembalikan nomor baris item dalam daftar nilai. Ini sangat berguna untuk situasi seperti ini. Jika Anda benar-benar ingin terjun ke dunia splitter, berikut adalah beberapa pilihan bagus lainnya. http://sqlperformance.com/2012/07/t-sql -queries/split-string
Anda dapat membaca lebih lanjut tentang tab silang dinamis di sini. http://www.sqlservercentral.com/articles/Crosstab/65048/
Saya tidak begitu mengerti apa hubungan tabel #STATICFILTER dengan ini, jadi saya mengabaikannya.
Pastikan Anda memahami kode ini sebelum menerapkannya. Artikel yang direferensikan membahas teknik ini dengan sangat rinci.
if OBJECT_ID('tempdb..#MathTemp1') is not null
drop table #MathTemp1
CREATE TABLE #MathTemp1
(
IDNUM INTEGER IDENTITY(1,1),
YEARMONTH VARCHAR(256),
OutputFormula VARCHAR(256),
Timedimensiondate Date
)
INSERT INTO #MathTemp1 (YEARMONTH,OUTPUTFORMULA,Timedimensiondate)
VALUES ('CV(N2) 1989: 1','2641.000 + Import - Consumption customs value(1540) + Import - Consumption customs value(1541)','1989-01-01')
,('CV(N2) 1989: 10','54407.000 + Import - Consumption customs value(1540) + 63906.000','1989-10-01')
,('CV(N2) 1990: 11','Import - Consumption customs value(2266) + Import - Consumption customs value(1540) + 53088.000','1990-11-01')
,('CV(N2) 1994: 5','32852.000 + Import - Consumption customs value(1540) + Import - Consumption customs value(1541)','1994-05-01')
declare @StaticPortion nvarchar(2000) =
'with OrderedResults as
(
select mt.IDNUM
, mt.OutputFormula
, mt.Timedimensiondate
, mt.YEARMONTH
, x.ItemNumber
, LTRIM(RTRIM(x.Item)) as Item
from #MathTemp1 mt
cross apply dbo.DelimitedSplit8K(mt.OutputFormula, ''+'') x
)
Select IDNUM';
declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by IDNUM order by IDNUM';
with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select @DynamicPortion = @DynamicPortion +
', MAX(Case when ItemNumber = ' + CAST(N as varchar(6)) + 'then case when ISNUMERIC(Item) = 1 then convert(numeric(9,3), ltrim(rtrim(Item))) else 0 end end) as Value' + CAST(N as varchar(6)) + CHAR(10)
from cteTally t
where t.N <=
(
select MAX(LEN(OutputFormula) - LEN(replace(OutputFormula, '+', ''))) + 1
from #MathTemp1
)
declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
--select @SqlToExecute
exec sp_executesql @SqlToExecute