sql >> データベース >  >> RDS >> Sqlserver

SQLで特定の文字列のアルファベットをゼロに置き換える

    これを行うには、ある程度高度な技術をいくつか組み合わせる必要があります。最初の問題は、データが区切られていることです。複数の値を 1 つのセルに詰め込むと、これは 1NF に違反します。パズルの 2 番目のピースは、このデータを動的な数の列に PIVOT する方法です。 SO の周りのほとんどの人は、動的な PIVOT を使用することを好みます。代わりに動的クロス集計を使用することを好みます。構文はそれほど鈍くなく、動的なクロス集計よりも少しだけパフォーマンスが高いと思います。

    私が通常使用するスプリッターについては、こちらを参照してください。 http://www.sqlservercentral.com/articles/Tally+Table/72993/ このスプリッターが提供する主な利点は、値のリスト内のアイテムの行番号を返すことです。これは、この種の状況に非常に役立ちます。本当にスプリッターの世界に飛び込みたい場合は、他にも優れたオプションがいくつかあります。 http://sqlperformance.com/2012/07/t-sql -クエリ/分割文字列

    動的クロス集計の詳細については、こちらをご覧ください。 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
    



    1. MySQLWITHROLLUPが期待したものを表示しない

    2. EntityFramework-MySQL-日時形式の問題

    3. 非標準の週の最初の日を使用して、Oracleで週を計算するにはどうすればよいですか?

    4. SSIS-関連する列を取得するために別のテーブルでルックアップを実行する