sql >> Database >  >> RDS >> Sqlserver

Alfabetten vervangen door nul in een bepaalde tekenreeks in SQL

Hiervoor zijn een aantal enigszins geavanceerde technieken nodig. Het eerste probleem is dat je gegevens hebt gescheiden. Dit schendt 1NF wanneer u meerdere waarden in een enkele cel propt. Het tweede stukje van de puzzel is hoe deze gegevens in een dynamisch aantal kolommen kunnen worden gedraaid. De meeste mensen rond SO gebruiken liever een dynamische PIVOT. Ik gebruik liever een dynamische kruistabel. Ik vind de syntaxis minder stompzinnig en het is zelfs een beetje performanter dan een dynamische kruistabel.

Je kunt hier lezen over de splitter die ik meestal gebruik. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Het belangrijkste voordeel van deze splitter dat de meeste andere niet hebben, is dat het het rijnummer van het item in de zoeklijst retourneert. Dit is ongelooflijk handig voor dit soort situaties. Als je echt in de splitterwereld wilt duiken, zijn hier verschillende andere uitstekende opties. http://sqlperformance.com/2012/07/t-sql -queries/split-strings

U kunt hier meer lezen over dynamische kruistabellen. http://www.sqlservercentral.com/articles/Crosstab/65048/

Ik begrijp niet echt wat de #STATICFILTER-tabel hiermee te maken heeft, dus negeerde ik het gewoon.

Zorg ervoor dat u deze code begrijpt voordat u deze implementeert. De artikelen waarnaar wordt verwezen, gaan uitgebreid in op deze technieken.

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. verschillende telling(*)

  2. MySQL - één op één relatie?

  3. Rijen van twee tabellen bijwerken die beperkingen voor refererende sleutels hebben

  4. Mysql - LIMIET per percentage?