sql >> Database teknologi >  >> RDS >> Sqlserver

Udskiftning af alfabeter til nul i en given streng i SQL

Dette kræver en række lidt avancerede teknikker kombineret for at gøre dette. Det første problem er, at du har afgrænsede data. Dette overtræder 1NF, når du propper flere værdier ind i en enkelt celle. Den anden brik i puslespillet er, hvordan man PIVOT disse data til et dynamisk antal kolonner. De fleste mennesker omkring SO foretrækker at bruge en dynamisk PIVOT. Jeg foretrækker i stedet at bruge en dynamisk krydsfane. Jeg synes, at syntaksen er mindre stump, og den er endda en lille smule mere effektiv end en dynamisk krydsfane.

Du kan læse om den splitter jeg typisk bruger her. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Den største fordel, som denne splitter tilbyder, som de fleste andre ikke gør, er, at den returnerer rækkenummeret på elementet på listen over værdier. Dette er utroligt nyttigt til denne type situation. Hvis du virkelig vil dykke ned i splitterverdenen, er her flere andre fremragende muligheder. http://sqlperformance.com/2012/07/t-sql -queries/split-strings

Du kan læse mere om Dynamiske krydsfaner her. http://www.sqlservercentral.com/articles/Crosstab/65048/

Jeg forstår ikke rigtig, hvad #STATICFILTER-tabellen har med dette at gøre, så jeg ignorerede den bare.

Sørg for, at du forstår denne kode, før du implementerer den. De refererede artikler går i detaljer om disse teknikker.

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. Rollback virker ikke i oracle ved hjælp af liquibase

  2. Skal jeg køre mysql på google cloud run? (eller enhver database)

  3. Overførsel af parametre til en JDBC PreparedStatement

  4. Jeg har brug for en funktion til at vælge 88 tilfældige rækker fra en tabel (uden dubletter)