2016-12-27 4 views
0

既知のアルファ部分文字列を削除し、10進数の後に2桁の数字を表示するようにフォーマットしようとしています。アルファ文字を削除してSQLで数字をフォーマットする方法

select tbl.result 
, case 
    when CHARINDEX('searchCriteria',tbl.result) > 0 then case 
     when ISNUMERIC(REPLACE(tbl.result, 'searchCriteria', '')) > 0 then TRY_CONVERT(decimal(18,2),REPLACE(tbl.result, 'searchCriteria', '')) 
    else REPLACE(tbl.result, 'searchCriteria', '') 
    end 
else tbl.result 
end as [Substring_Removed] 
from sourceTable tbl 


--Msg 8114, Level 16, State 5, Line 71 
--Error converting data type varchar to numeric. 

Data Type Precedence私はこれを回避するために使用することができますどのような戦略

に問題が?結果列の

典型的な値は、スタイルである:

  • < 123 searchCriteria
  • 123 searchCriteria
  • 1.23
  • 123000 searchCriteria
  • 1.23x10e8 searchCriteria
+3

サンプルデータと望ましい結果が役立ちます –

+0

代表的なデータは、数値の後に小節の単位、または手動で入力された値が続きます。私は10進数の後に2桁で表示された測定単位のない数値を表示したいと思います。 1,234.5 g/Lは1234.50と表示されます –

+0

ソース列に手動で入力された値の例は「測定されません」 –

答えて

0
This is assuming "SomeString" begins with a number and has a space after the value. 


Declare @YourTable table (ID int,SomeString varchar(50)) 
Insert Into @YourTable values 
(1,'<123 searchCriteria'), 
(2,'123 searchCriteria'), 
(3,'1.23'), 
(4,'123,000 searchCriteria'), 
(5,'1.23x10e8 searchCriteria'), 
(6,'1,234.5 g/L'), 
(7,'Not measured') 


Select * 
     ,TheValue = IsNull(Format(Try_Convert(float,Replace(Replace(Replace(Left(SomeString,CharIndex(' ',SomeString+' ')),',',''),'x10',''),'<','')),'#0.00'),SomeString) 
From @YourTable 

戻りますがhereを見つけることができPatExclude8Kを使用

ID SomeString     TheValue 
1 <123 searchCriteria   123.00 
2 123 searchCriteria   123.00 
3 1.23      1.23 
4 123,000 searchCriteria  123000.00 
5 1.23x10e8 searchCriteria 123000000.00 
6 1,234.5 g/L     1234.50 
7 Not measured    Not measured 
+0

この解決策は良い科学的表記法です。しかし、「非測定」のような数値以外の結果はゼロになります。これは私の状況では機能しません。また、各数値入力に2桁の小数点が必要です。 –

+0

@DanR更新された回答を参照してください。 –

+0

私の要件に関して明確でないことをお詫びします。数値以外の結果は変更されずに表示されるはずです。数値を伴わない場合は、「測定されていません」と表示されます。 –

0

、あなたはこれを行うことができます:

-- Sample Data 
Declare @YourTable table (ID int,SomeString varchar(50)) 
Insert Into @YourTable values 
(1,'<123 searchCriteria'), 
(2,'123 searchCriteria'), 
(3,'1.23'), 
(4,'123,000 searchCriteria'), 
(5,'1.23x10e8 searchCriteria'), 
(6,'1,234.5 g/L'), 
(7,'Not measured') 

-- Solution: 
SELECT yt.*, [Substring_Removed] = 
     ISNULL(CAST(CAST(NewString AS decimal(10,2)) AS varchar(12)), SomeString) 
FROM @YourTable yt 
CROSS APPLY dbo.PatExclude8K(SomeString, '[^0-9.]'); 

結果:できない人のために更新

ID   SomeString     Substring_Removed 
----------- ---------------------------- ----------------- 
1   <123 searchCriteria   123.00 
2   123 searchCriteria   123.00 
3   1.23       1.23 
4   123,000 searchCriteria  123000.00 
5   1.23x10e8 searchCriteria  1.23 
6   1,234.5 g/L     1234.50 
7   Not measured     Not measured 

を新しい機能を使用してください...

は、ここで適切なソリューションの中で焼いpatexclude8K機能です:

-- Sample Data 
Declare @YourTable table (ID int,SomeString varchar(50)) 
Insert Into @YourTable values 
(1,'<123 searchCriteria'), 
(2,'123 searchCriteria'), 
(3,'1.23'), 
(4,'123,000 searchCriteria'), 
(5,'1.23x10e8 searchCriteria'), 
(6,'1,234.5 g/L'), 
(7,'Not measured') 

-- new solution with Patexclude8K logic baked in 
SELECT yt.*, substring_removed = ISNULL(CAST(CAST(NewString AS decimal(10,2)) AS varchar(12)), yt.SomeString) 
FROM @yourTable yt 
CROSS APPLY 
(
    SELECT SUBSTRING(yt.someString, N, 1) 
    FROM 
    (
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) 
    FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) a(x), 
     (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) b(x), 
     (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) c(x), 
     (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) d(x) 
) iTally(N) 
    WHERE N <= (CONVERT(INT,LEN(yt.someString),0)) 
    AND 0 = PATINDEX('[^0-9.]',SUBSTRING(yt.someString COLLATE Latin1_General_BIN,N,1)) 
    FOR XML PATH('') 
) patexclude(newstring); 

結果は同じですが、この方法は、特別な扱いが特殊なXML文字のために必要ではないので、私はもともと投稿何よりも約40%速くなります。

+0

これらの結果は私が期待するものです。残念ながら、このプロジェクトでは、アドオン機能を実装することはできません。 –

+0

追加機能を必要としないように私のソリューションを更新しました。更新されたソリューションでは、CROSS APPLYを使用してpatexclude8K機能がクエリに焼き付けられます。 –

関連する問題