Това изисква редица донякъде усъвършенствани техники, комбинирани за това. Първият проблем е, че имате разделени данни. Това нарушава 1NF, когато натъпчете множество стойности в една клетка. Второто парче от пъзела е как да PIVOT тези данни в динамичен брой колони. Повечето хора около SO предпочитат да използват динамичен PIVOT. Вместо това предпочитам да използвам динамичен напречен раздел. Намирам синтаксиса за по-малко тъп и дори е малко по-ефективен от динамичен напречен раздел.
Можете да прочетете за сплитера, който обикновено използвам тук. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Основното предимство, което този сплитер предлага, което повечето други не предлагат, е, че връща номера на реда на елемента в списъка със стойности. Това е невероятно полезно за този тип ситуации. Ако наистина искате да се потопите в света на сплитерите, ето няколко други отлични опции. http://sqlperformance.com/2012/07/t-sql -queries/split-strings
Можете да прочетете повече за динамичните кръстосани раздели тук. http://www.sqlservercentral.com/articles/Crosstab/65048/
Наистина не разбирам какво общо има таблицата #STATICFILTER с това, така че просто я игнорирах.
Уверете се, че разбирате този код, преди да го приложите. Посочените статии разглеждат много подробно тези техники.
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