2016-07-11 40 views
0

数式の入力文字列をゼロに置き換えようとしています。私は特定の文字列のためにそれを行うことができましたが、以下の#mathtempテーブルにリストされているすべての文字列に対して実行できませんでした。SQL内の指定された文字列のアルファベットをゼロに置換する

私は入力の名前を持っています。私は数式を持っていますし、数字(値)を持たない文字列を0に戻すだけです。私が把握することができないreplace文には何らかの間違いがあります。

ISNUMERICを使用してこの処理を試みましたが、必要な出力が得られませんでした。これを行う、または以下を解決するための新しい考えがあるかどうかを教えてください。

BEGIN 
DECLARE @INPUTCOUNT AS INTEGER 
DECLARE @formulacount as integer 
DECLARE @in as int 
DECLARE @ia as int 
DECLARE @OUTPUTFORMULATrade as nvarchar(160) 
set @ia = 1 
set @in = 1 



CREATE TABLE #STATICFILTER 
(
IDNUM INTEGER IDENTITY(1,1), 
STATICNAME Varchar(160), 
) 

INSERT INTO #STATICFILTER (STATICNAME) 
VALUES ('Import - Consumption customs value(2266)') ,('Import - Consumption customs value(1540)') ,('Import - Consumption customs value(1541)') 


SET @INPUTCOUNT = (select count(*) from #STATICFILTER) 

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') 
SET @formulacount = (select count(*) from #MathTemp1) 

while (@ia < @formulacount) 
begin 
WHILE (@in < @INPUTCOUNT) 
BEGIN 
SET @OUTPUTFORMULATrade = (Select Replace ((SELECT REPLACE(OUTPUTFORMULA,(select STATICNAME from #STATICFILTER where IDNUM = @in),0)FROM #MathTemp1 WHERE IDNUM = @ia),(select STATICNAME from #STATICFILTER where IDNUM = @in+1),0)) 
SET @in = @in + 1 
END 
SET @ia = @ia + 1 
SET @in =1 
Select @OUTPUTFORMULATrade AS New 
END 
drop table #MathTemp1 
drop table #STATICFILTER 

END 

ますのでご注意ください入力は#staticfilterテーブルにランダムな形式で配置されており、同様に#mathtempテーブルは、入力式のいずれかの組み合わせを持っているかもしれません。

私の希望する出力は、任意の数式の文字列をゼロに置き換えることです。

2641.000 + 0 + 0 
54407.000 + 0 + 63906.000 
0 + 0 + 53088.000 
+1

正規表現を試しましたか? – dcod

+1

サンプルデータの出力はどのようなものですか?ネストされたwhileループアプローチは、これを処理する良い方法のようには見えません。 –

+0

@dcod正規表現とSQLサーバは、CLR以外では一度も関連付けられていません。 –

答えて

1

これは、これを行うために組み合わせるやや高度なテクニックの数を取るの下に確認してください。最初の問題は、データを区切ったことです。 1つのセルに複数の値を詰め込むと、これは1NFに違反します。パズルの第2の部分は、このデータを動的な列数にPIVOTする方法です。 SOの周りのほとんどの人は動的PIVOTを使用することを好みます。私は代わりに動的なクロスタブを使用することをお勧めします。私は構文が鈍いことがわかり、動的クロス・タブよりもパフォーマンスが少し上がっています。

ここでよく使用するスプリッタについて読むことができます。 http://www.sqlservercentral.com/articles/Tally+Table/72993/このスプリッタが提供する主な利点は、他のほとんどの人には分かりませんが、値リスト内の項目の行番号を返すことです。これは、この種の状況には非常に便利です。あなたがスプリッタの世界に実際にダイビングしたいのであれば、ここにいくつかの優れたオプションがあります。 http://sqlperformance.com/2012/07/t-sql-queries/split-strings

ダイナミッククロスタブの詳細については、こちらをご覧ください。 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 
+0

おかげで多くの男...あなたは私の時間のほとんどを保存.....私はこの1つをチェックして投票する... –

関連する問題