У мене є стовпець, DECIMAL(9,6)
тобто він підтримує такі значення, як 999,123456.
Але коли я вставляю такі дані, як 123,4567, це стає 123,456700
Як прибрати ці нулі?
У мене є стовпець, DECIMAL(9,6)
тобто він підтримує такі значення, як 999,123456.
Але коли я вставляю такі дані, як 123,4567, це стає 123,456700
Як прибрати ці нулі?
Відповіді:
Магазин decimal(9,6)
зберігає 6 цифр праворуч від коми. Відображати кінцеві нулі чи ні - це рішення щодо форматування, яке зазвичай реалізується на стороні клієнта.
Але оскільки формати SSMS float
не мають нульових нулів, ви можете видалити кінцеві нулі, додавши значення decimal
a 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
або більше REAL), оскільки обмежена точність подання машини викликає небажані ефекти:
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 може представляти
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
Якщо ви хочете, щоб у вашому номері був хоча б один нуль, тому 2.0 не стає 2, використовуйте рядок форматування типу 0.0#####
Десяткова крапка локалізована, тому культури, які використовують кому як десятковий роздільник, будуть зустрічатися з комою, де. є
Звичайно, це відчайдушна практика, коли рівень даних робить форматування (але в моєму випадку іншого рівня немає; користувач буквально запускає збережену процедуру і розміщує результат у електронному листі: /)
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
відбитки:
2.55
Cast(20.5500 as Decimal(6,2))
повинен це зробити.
Спробуйте це :
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 чи GREEN перед конвертацією через ймовірність втрати точності. Тож безпечні шляхи можуть бути приблизно такими:
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)
sp_
для збереженої процедури, fn_
для функцій, tbl
для таблиць тощо. на ... це не є вимогою, але це найкраща практика організації наших баз даних.
У мене була подібна проблема, необхідна для обрізання кінцевих нулів із таких чисел, як 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')
, '.', ' ')), ' ', '.')
Середня лінія знімає кінцеві пробіли, дві зовнішні видаляють точку, якщо немає десяткових цифр
Мені потрібно було видалити кінцеві нулі з моїх десяткових знаків, щоб я міг вивести рядок певної довжини лише з початковими символами нулями
(наприклад, мені потрібно було вивести 14 символів, щоб 142.023400 стало 000000142.0234),
Я використовував 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'),'.',' ')),' ','.')
Як щодо цього? Якщо припустити, що дані надходять у вашу функцію як @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
Я розумію, що це стара публікація, але я хотів би надати 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(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
Найпростіший спосіб - ПРИЛОЖИТИ значення як FLOAT, а потім до типу даних рядка.
CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
Спробуйте це:
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
, ОП просить видалити кінцеві нулі.
ДЕКРАМОВИЙ (9,6) стовпець перетвориться на плаваючий без втрати точності, тому CAST (... AS float) зробить трюк.
@HLGEM: твердження, що float - це поганий вибір для зберігання чисел, а "Ніколи не використовувати float" - неправильно - ви просто повинні знати свої номери, наприклад, вимірювання температури було б чудово, як плаваючі.
@abatishchev та @japongskie: префікси перед SQL-процесами та функціями, що зберігаються, все ще є гарною ідеєю, якщо не потрібні; посилання, про які ви згадали, лише вказують не використовувати префікс "sp_" для збережених процедур, які ви не повинні використовувати, інші префікси чудові, наприклад "usp_" або "spBob_"
Посилання: "Усі цілі числа з 6 або менше значущих десяткових цифр можуть бути перетворені у значення з плаваючою комою IEEE 754 без втрати точності": https://en.wikipedia.org/wiki/Single-precision_floating-point_format