Điều này cần một số kỹ thuật hơi nâng cao kết hợp để thực hiện điều này. Vấn đề đầu tiên là bạn có dữ liệu được phân tách. Điều này vi phạm 1NF khi bạn nhồi nhét nhiều giá trị vào một ô duy nhất. Phần thứ hai của câu đố là làm thế nào để CHUYỂN dữ liệu này thành một số cột động. Hầu hết mọi người xung quanh SO thích sử dụng PIVOT động. Thay vào đó, tôi thích sử dụng một tab chéo động. Tôi thấy cú pháp này ít khó hiểu hơn và nó thậm chí còn hiệu quả hơn một chút so với tab chéo động.
Bạn có thể đọc về bộ chia mà tôi thường sử dụng ở đây. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Ưu điểm chính mà bộ tách này cung cấp mà hầu hết những người khác không có là nó trả về số hàng của mục trong danh sách các giá trị. Điều này cực kỳ hữu ích cho loại tình huống này. Nếu bạn thực sự muốn đi sâu vào thế giới bộ chia, đây là một số lựa chọn tuyệt vời khác. http://sqlperformance.com/2012/07/t-sql -query / split-string
Bạn có thể đọc thêm về Tab chéo động tại đây. http://www.sqlservercentral.com/articles/Crosstab/65048/
Tôi thực sự không hiểu bảng #STATICFILTER có liên quan gì với điều này nên tôi đã bỏ qua nó.
Đảm bảo rằng bạn hiểu mã này trước khi triển khai. Các bài báo tham khảo đi sâu vào chi tiết về các kỹ thuật này.
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