列があります。DECIMAL(9,6)
つまり、999,123456のような値をサポートしています。
しかし、123,4567のようなデータを挿入すると、123,456700になります
それらのゼロを削除する方法は?
列があります。DECIMAL(9,6)
つまり、999,123456のような値をサポートしています。
しかし、123,4567のようなデータを挿入すると、123,456700になります
それらのゼロを削除する方法は?
回答:
Adecimal(9,6)
は、コンマの右側に6桁を格納します。末尾のゼロを表示するかどうかはフォーマットの決定であり、通常はクライアント側で実装されます。
ただし、SSMSはfloat
後続ゼロなしでフォーマットするdecimal
ため、 float
:にキャストすることで後続ゼロを削除できます。
select
cast(123.4567 as DECIMAL(9,6))
, cast(cast(123.4567 as DECIMAL(9,6)) as float)
プリント:
123.456700 123,4567
(私の小数点記号はコンマですが、SSMSは小数点をドットでフォーマットします。明らかに既知の問題です。)
FORMAT()
関数(SqlAzureおよびSql Server 2012+)を使用できます。
SELECT FORMAT(CAST(15.12 AS DECIMAL(9,6)), 'g18') -- '15.12'
SELECT FORMAT(CAST(0.0001575 AS DECIMAL(9,6)), 'g10') -- '0.000158'
SELECT FORMAT(CAST(2.0 AS DECIMAL(9,6)), 'g15') -- '2'
FLOAT(またはREAL)で使用する場合は注意してください。マシン表現の精度が制限されていると望ましくない影響が生じるため、使用しないでください(またはREALではg17
それg8
以上)。
SELECT FORMAT(CAST(15.12 AS FLOAT), 'g17') -- '15.119999999999999'
SELECT FORMAT(CAST(0.9 AS REAL), 'g8') -- '0.89999998'
SELECT FORMAT(CAST(0.9 AS REAL), 'g7') -- '0.9'
さらに、ドキュメントによると、次の点に注意してください。
FORMATは、.NET Framework共通言語ランタイム(CLR)の存在に依存しています。この関数は、CLRの存在に依存するため、リモート化されません。CLRを必要とする関数をリモート処理すると、リモートサーバーでエラーが発生します。
SqlAzureでも動作します。
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
floatが表すことができるよりも多くの桁が小数に含まれる可能性があるため、floatにキャストすることには消極的でした。
FORMAT
標準の.net形式の文字列 'g8'を使用すると、小数点以下が非常に小さい場合(1e-08など)に科学的記数法が返されますが、これも不適切でした。
カスタムフォーマット文字列(https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings)を使用すると、目的を達成できました。
DECLARE @n DECIMAL(9,6) =1.23;
SELECT @n
--> 1.230000
SELECT FORMAT(@n, '0.######')
--> 1.23
数値の末尾にゼロを少なくとも1つ含めて、2.0が2にならないようにする場合は、次のようなフォーマット文字列を使用します。 0.0#####
小数点はローカライズされているため、小数点記号としてコンマを使用するカルチャでは、コンマ出力が発生します。です
もちろん、これはデータレイヤーにフォーマットを実行させるというお勧めできない方法です(ただし、私の場合、他のレイヤーはありません。ユーザーは文字通りストアドプロシージャを実行し、結果を電子メールに入れています:/)
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
プリント:
2.55
これを試して :
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
20.55を与える
0.000
なりました.
。これがSELECT REPLACE(RTRIM(REPLACE(20.5500, "0", " ")), " ", "0")
後続ゼロのみをトリムするための修正です
同様の問題がありましたが、小数点が存在しない小数点を削除する必要もありました。これは、小数点をそのコンポーネントに分割し、小数点文字列から取得する文字数を次の長さに基づいて計算するソリューションです。分数成分(CASEを使用しない)。さらに興味深いことに、私の数値は小数点なしの浮動小数点数として格納されていました。
DECLARE @MyNum FLOAT
SET @MyNum = 700000
SELECT CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),2) AS VARCHAR(10))
+ SUBSTRING('.',1,LEN(REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0')))
+ REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0')
結果は痛いです、私は知っています、しかし私は上記の答えから多くの助けを借りてそこに着きました。
精度が低下する可能性があるため、変換する前にFLOATまたはMONEYに変換しないのが最善の方法です。したがって、安全な方法は次のようになります。
CREATE FUNCTION [dbo].[fn_ConvertToString]
(
@value sql_variant
)
RETURNS varchar(max)
AS
BEGIN
declare @x varchar(max)
set @x= reverse(replace(ltrim(reverse(replace(convert(varchar(max) , @value),'0',' '))),' ',0))
--remove "unneeded "dot" if any
set @x = Replace(RTRIM(Replace(@x,'.',' ')),' ' ,'.')
return @x
END
ここで、@ valueは任意のdecimal(x、y)にすることができます
sp_
、ストアドプロシージャ、fn_
関数、tbl
テーブルなどに使用します。 on ...これは必須ではありませんが、データベースを整理するためのベストプラクティスです。
同様の問題があり、次のような数値から後続ゼロをトリミングする必要がありました xx0000,x00000,xxx000
私が使用した:
select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename
コードは、トリミングする番号が付いたフィールドの名前です。これが他の誰かに役立つことを願っています。
小数の末尾のゼロを削除して、先頭のみで特定の長さの文字列を出力できるようにする必要がありましたゼロ
(たとえば、142.023400が000000142.0234になるように14文字を出力する必要がありました)、
私が使用されparsename
、reverse
そしてcast
as int
後続のゼロを削除するには:
SELECT
PARSENAME(2.5500,2)
+ '.'
+ REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))
(次に、先行ゼロを取得するために、上記の長さに基づいて正しい数のゼロを複製し、これを上記の前に連結することができます)
これが誰かに役立つことを願っています。
TSQLで先頭と末尾のゼロを削除することが可能です
文字列でない場合は、STR TSQL関数を使用して文字列に変換し、次に
先頭と末尾の両方のゼロを削除します
SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
フォーラムの詳細情報。
REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(REPLACE(X,'0',' ')),' ','0'),'.',' ')),' ','.')
case when left(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.'
then '0'
else ''
end +
replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0') +
case when right(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.'
then '0'
else ''
end
これは古い投稿であることを理解していますが、私が思いついたSQLを提供したいと思います
DECLARE @value DECIMAL(23,3)
set @value = 1.2000
select @value original_val,
SUBSTRING( CAST( @value as VARCHAR(100)),
0,
PATINDEX('%.%',CAST(@value as VARCHAR(100)))
)
+ CASE WHEN ROUND(
REVERSE( SUBSTRING( CAST(@value as VARCHAR(100)),
PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1,
LEN(CAST(@value as VARCHAR(100)))
)
)
,1) > 0 THEN
'.'
+ REVERSE(ROUND(REVERSE(SUBSTRING( CAST(@value as VARCHAR(100)),
PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1,
LEN(CAST(@value as VARCHAR(100)))
)
),1))
ELSE '' END AS modified_val
これを試して:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
このスレッドは非常に古いことは知っていますが、SQL Server 2012以降を使用していない場合、または何らかの理由でFORMAT関数を使用できない場合は、次のように機能します。
また、数が1未満の場合(例:0.01230000)、多くのソリューションが機能しませんでした。
以下は負の数では機能しないことに注意してください。
DECLARE @num decimal(28,14) = 10.012345000
SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0')
set @num = 0.0123450000
SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0')
それぞれ10.012345と0.012345を返します。
これを試して:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
999999
、OPは後続のゼロを削除するように要求しています。
DECIMAL(9,6)列は、精度を失うことなくfloatに変換されるため、CAST(... AS float)でうまくいきます。
@HLGEM:フロートは数値を保存するのに不適切な選択であり、「フロートを使用しない」は正しくありません。たとえば、温度測定はフロートとしてうまくいくので、数値を知っている必要があります。
@abatishchevおよび@japongskie:SQLストアドプロシージャおよび関数の前にプレフィックスを付けることは、必要でない場合でも良い考えです。あなたが言及したリンクは、使用すべきでないストアドプロシージャに「sp_」プレフィックスを使用しないように指示するだけです。他のプレフィックス(「usp_」や「spBob_」など)は問題ありません。
参照:「小数点以下6桁以下のすべての整数は、精度を失うことなくIEEE 754浮動小数点値に変換できます」:https://en.wikipedia.org/wiki/Single-precision_floating-point_format