sql >> Databasteknik >  >> RDS >> Sqlserver

Byt ut alfabet till noll i en given sträng i SQL

Detta kräver ett antal något avancerade tekniker kombinerat för att göra detta. Det första problemet är att du har avgränsade data. Detta bryter mot 1NF när du klämmer in flera värden i en enda cell. Den andra pusselbiten är hur man PIVOTAR denna data till ett dynamiskt antal kolumner. De flesta människor runt SO föredrar att använda en dynamisk PIVOT. Jag föredrar att använda en dynamisk korsflik istället. Jag tycker att syntaxen är mindre trubbig och den är till och med lite mer presterande än en dynamisk korsflik.

Du kan läsa om splittern jag vanligtvis använder här. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Den största fördelen med denna splitter som de flesta andra inte har är att den returnerar radnumret för objektet i värdelistan. Detta är otroligt användbart för den här typen av situationer. Om du verkligen vill dyka in i splittervärlden finns här flera andra utmärkta alternativ. http://sqlperformance.com/2012/07/t-sql -queries/split-strings

Du kan läsa mer om Dynamiska kryssflikar här. http://www.sqlservercentral.com/articles/Crosstab/65048/

Jag förstår inte riktigt vad #STATICFILTER-tabellen har med detta att göra så jag ignorerade den bara.

Se till att du förstår den här koden innan du implementerar den. De refererade artiklarna går in i detalj om dessa tekniker.

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



  1. Välj mellan flera bord med UNION

  2. I MySQL beräkna offset för en tidszon

  3. SQL Server Databas Replikering

  4. Hur ställer jag in veckovis automatisk säkerhetskopiering i SQL Server 2012?