SQL Server의 십진수에서 후행 0 제거
DECIMAL(9,6)999,123456과 같은 값을 지원 하는 열이 있습니다 .
하지만 123,4567과 같은 데이터를 삽입하면 123,456700이됩니다.
그 0을 제거하는 방법?
A decimal(9,6)는 쉼표 오른쪽에 6 자리 숫자를 저장합니다. 후행 0을 표시할지 여부는 일반적으로 클라이언트 측에서 구현되는 형식 지정 결정입니다.
그러나 SSMS는 float후행 0이없는 형식이므로 decimal를 a 로 캐스트하여 후행 0을 제거 할 수 있습니다 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)와 함께 사용할 때는주의하십시오 . 기계 표현의 제한된 정밀도로 인해 원하지 않는 효과가 발생하므로 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
숫자 뒤에 0이 하나 이상 있어야하므로 2.0이 2가되지 않도록하려면 다음과 같은 형식 문자열을 사용하십시오. 0.0#####
소수점은 지역화되어 있으므로 쉼표를 소수점 구분 기호로 사용하는 문화권에서는. 이다
물론 이것은 데이터 레이어가 형식을 지정하는 것은 좋지 않습니다. (하지만 제 경우에는 다른 레이어가 없습니다. 사용자는 말 그대로 저장 프로 시저를 실행하고 결과를 이메일에 넣습니다. : /)
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
인쇄물:
2.55
Cast(20.5500 as Decimal(6,2))
해야합니다.
비슷한 문제가 있었지만 소수점이없는 소수점을 제거해야했습니다. 여기에 소수점을 구성 요소로 분할하고 소수점 문자열에서 가져온 문자 수를 분수 성분 (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 될 수있는 임의의 소수 (X, Y)
비슷한 문제가 있었는데, 다음과 같은 숫자에서 후행 0을 잘라 내야했습니다. xx0000,x00000,xxx000
나는 다음을 사용했다 :
select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename
코드는자를 번호가있는 필드의 이름입니다. 이것이 다른 사람에게 도움이되기를 바랍니다.
다른 옵션 ...
이것이 얼마나 효율적인지 모르겠지만 작동하는 것처럼 보이고 float를 통해 가지 않습니다.
select replace(rtrim(replace(
replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0')
, '.', ' ')), ' ', '.')
중간 선은 후행 공백을 제거하고 바깥 쪽 두 개는 소수점이없는 경우 점을 제거합니다.
소수의 후행 0을 제거하여 선행 0 만있는 특정 길이의 문자열을 출력해야했습니다.
(예 : 142.023400이 000000142.0234가되도록 14자를 출력해야했습니다),
parsename, reverse및 cast as int후행 0을 제거하기 위해 사용했습니다 .
SELECT
PARSENAME(2.5500,2)
+ '.'
+ REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))
(그런 다음 내 선행 0을 얻으려면 위의 길이에 따라 올바른 수의 0을 복제하고이를 위의 앞쪽에 연결할 수 있습니다)
나는 이것이 누군가에게 도움이되기를 바랍니다.
it is possible to remove leading and trailing zeros in TSQL
Convert it to string using STR TSQL function if not string, Then
Remove both leading & trailing zeros
SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccountMore info on forum.
Try this :
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
Gives 20.55
How about this? Assuming data coming into your function as @thisData:
BEGIN
DECLARE @thisText VARCHAR(255)
SET @thisText = REPLACE(RTRIM(REPLACE(@thisData, '0', ' ')), ' ', '0')
IF SUBSTRING(@thisText, LEN(@thisText), 1) = '.'
RETURN STUFF(@thisText, LEN(@thisText), 1, '')
RETURN @thisText
END
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
I understand this is an old post but would like to provide SQL that i came up with
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
try this.
select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
The easiest way is to CAST the value as FLOAT and then to a string data type.
CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
Try this:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
I know this thread is very old but for those not using SQL Server 2012 or above or cannot use the FORMAT function for any reason then the following works.
Also, a lot of the solutions did not work if the number was less than 1 (e.g. 0.01230000).
Please note that the following does not work with negative numbers.
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')
Returns 10.012345 and 0.012345 respectively.
Try this:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
A DECIMAL(9,6) column will convert to float without loss of precision, so CAST(... AS float) will do the trick.
@HLGEM: saying that float is a poor choice for storing numbers and "Never use float" is not correct - you just have to know your numbers, e.g. temperature measurements would go nicely as floats.
@abatishchev and @japongskie: prefixes in front of SQL stored procs and functions are still a good idea, if not required; the links you mentioned only instructs not to use the "sp_" prefix for stored procedures which you shouldn't use, other prefixes are fine e.g. "usp_" or "spBob_"
Reference: "All integers with 6 or fewer significant decimal digits can be converted to an IEEE 754 floating-point value without loss of precision": https://en.wikipedia.org/wiki/Single-precision_floating-point_format
참고URL : https://stackoverflow.com/questions/2938296/remove-trailing-zeros-from-decimal-in-sql-server
'developer tip' 카테고리의 다른 글
| SQLAlchemy 삽입이 sqlite3를 직접 사용하는 것보다 25 배 느린 이유는 무엇입니까? (0) | 2020.10.18 |
|---|---|
| index.php를 제외한 모든 .php 파일에 대한 직접 액세스 거부 (0) | 2020.10.18 |
| 컴파일 된 파일 크기를 줄이는 방법은 무엇입니까? (0) | 2020.10.18 |
| Lua의 For 루프 (0) | 2020.10.18 |
| 지난 24 시간 동안 날짜 필드가있는 레코드 찾기 (0) | 2020.10.18 |