Eliminar ceros finales del decimal en SQL Server


Tengo una columna DECIMAL(9,6) es decir, soporta valores como 999,123456.

Pero cuando inserto datos como 123,4567 se convierte en 123,456700

¿Cómo eliminar esos ceros?

Author: Espo, 2010-05-30

22 answers

A decimal(9,6) almacena 6 dígitos en el lado derecho de la coma. Si mostrar ceros finales o no es una decisión de formato, generalmente implementada en el lado del cliente.

Pero dado que los SSMS formatean float sin ceros finales, puede eliminar ceros finales fundiendo el decimal a un float:

select 
    cast(123.4567 as DECIMAL(9,6))
,   cast(cast(123.4567 as DECIMAL(9,6)) as float)

Impresiones:

123.456700  123,4567

(Mi separador decimal es una coma, sin embargo SSMS formatea decimal con un punto. Aparentemente un problema conocido.)

 110
Author: Andomar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-30 11:04:51

Puede usar la función FORMAT() (SqlAzure y 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'

Tenga cuidado al usar con FLOAT (o REAL): no use g17 o mayor (o g8 o mayor con REAL), porque la precisión limitada de la representación de la máquina causa efectos no deseados:

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'

Además, tenga en cuenta que, de acuerdo con la documentación :

EL FORMATO se basa en la presencia del Lenguaje Común. NET Framework Tiempo de ejecución (CLR). Esta función no será remoto ya que depende de la presencia del CLR. Remoting una función que requiere el CLR causaría un error en el servidor remoto.

También funciona en SqlAzure.

 23
Author: robert4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-08 05:18:47
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
 11
Author: Bat_Programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-22 23:37:32
SELECT REVERSE(ROUND(REVERSE(2.5500),1))

Impresiones:

2.55
 7
Author: user1959416,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-17 18:05:40
Cast(20.5500 as Decimal(6,2))

Debería hacerlo.

 3
Author: Peter Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-24 15:37:29

Era reacio a lanzar para flotar debido a la posibilidad de que haya más dígitos en mi decimal de lo que el flotador puede representar

FORMAT cuando se utiliza con una cadena de formato. net estándar,' g8 ' devuelve la notación científica en los casos de decimales muy pequeños (por ejemplo, 1e-08), que también era inadecuado

Usando una cadena de formato personalizado ( https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings) me permitió lograr lo que quería:

DECLARE @n DECIMAL(9,6) =1.23;
SELECT @n
--> 1.230000
SELECT FORMAT(@n, '0.######')
--> 1.23

Si desea que su número tenga al menos un cero final, para que 2.0 no se convierta en 2, use una cadena de formato como 0.0#####

El punto decimal está localizado, por lo que las culturas que usan una coma como separador decimal encontrarán una salida de coma donde el . is

Por supuesto, esta es la práctica desalentadora de tener la capa de datos haciendo formateo (pero en mi caso no hay otra capa; el usuario está literalmente ejecutando un procedimiento almacenado y poniendo el resultado en un correo electrónico:/)

 3
Author: Caius Jard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-26 10:00:39

Tuve un problema similar, pero también tuve que eliminar el punto decimal donde no había decimal presente, aquí estaba mi solución que divide el decimal en sus componentes, y basa el número de caracteres que toma de la cadena de punto decimal en la longitud del componente de fracción (sin usar MAYÚSCULAS y minúsculas). Para hacer las cosas aún más interesantes, mi número fue almacenado como un flotador sin sus decimales.

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') 

El resultado es doloroso, lo sé, pero llegué allí, con mucha ayuda de la respuestas arriba.

 2
Author: Adge Cutler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-03 09:30:41

La mejor manera es NO convertir a FLOTAR o DINERO antes de convertir debido a la posibilidad de pérdida de precisión. Así que las formas seguras pueden ser algo como esto :

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

Donde @value puede ser cualquier decimal (x,y)

 2
Author: Mahmoud Moravej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-12 04:37:41

Necesitaba eliminar ceros finales en mis decimales para poder generar una cadena de cierta longitud con solo ceros iniciales

(por ejemplo, necesitaba generar 14 caracteres para que 142.023400 se convirtiera en 000000142.0234),

He utilizado parsename, reverse y cast as int para eliminar los ceros finales:

SELECT
    PARSENAME(2.5500,2)
    + '.'
    + REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))

(Para entonces obtener mis ceros a la izquierda podría replicar el número correcto de ceros basado en la longitud de la anterior y concatenar esto al frente de la supra)

Espero que esto ayude a alguien.

 1
Author: Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-25 11:50:51

Es posible eliminar ceros iniciales y finales en TSQL

  1. Si no es string, Entonces

  2. Eliminar los ceros iniciales y finales

    SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
    
  3. Más información en forum .

 1
Author: Ishtiaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 18:02:14

Prueba esto:

SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")

Da 20.55

 1
Author: Todd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-18 11:25:08

Otra opción...

No se que tan eficiente es esto pero parece funcionar y no va a través de flotador:

select replace(rtrim(replace(
       replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0')
       , '.', ' ')), ' ', '.')

La línea media elimina los espacios finales, los dos exteriores eliminan el punto si no hay dígitos decimales

 0
Author: SQLian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-07 13:49:59

¿Qué tal esto? Suponiendo que los datos que entran en su función como @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
 0
Author: MrNazgul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-31 01:32:45
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
 0
Author: beloblotskiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 07:15:10

Entiendo que este es un post antiguo, pero me gustaría proporcionar SQL que se me ocurrió

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
 0
Author: Abhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-23 20:19:54

Sé que este hilo es muy antiguo, pero para aquellos que no usan SQL Server 2012 o superior o no pueden usar la función de FORMATO por cualquier razón, entonces lo siguiente funciona.

Además, muchas de las soluciones no funcionaban si el número era inferior a 1 (por ejemplo, 0.01230000).

Tenga en cuenta que lo siguiente no funciona con números negativos.

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') 

Devuelve 10.012345 y 0.012345 respectivamente.

 0
Author: Alan Schofield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-16 13:15:52

Prueba esto.

select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
 0
Author: Vishal Kiri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-09 08:38:38

La forma más fácil es CONVERTIR el valor como FLOTANTE y luego a un tipo de datos de cadena.

CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
 0
Author: Brad Raiche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-30 15:55:24

Tuve un problema similar, necesitaba recortar ceros finales de números como xx0000,x00000,xxx000

He utilizado:

select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename

Code es el nombre del campo con el número a recortar. Espero que esto ayude a alguien más.

 0
Author: Kazeem Muritala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-10 16:57:55

Una columna DECIMAL(9,6) se convertirá en flotante sin pérdida de precisión, por lo que CAST(... COMO flotador) hará el truco.


@HLGEM: decir que float es una mala opción para almacenar números y "Nunca uses float" no es correcto - solo tienes que conocer tus números, por ejemplo, las mediciones de temperatura irían bien como floats.

@abatishchev y @japongskie: los prefijos delante de los procs y funciones almacenados en SQL siguen siendo una buena idea, si no es necesario; los enlaces que mencionó solo indica que no debe usar el prefijo " sp_ " para procedimientos almacenados que no debe usar, otros prefijos están bien, por ejemplo, "usp_" o "spBob_"

Referencia: "Todos los enteros con 6 o menos dígitos decimales significativos se pueden convertir a un valor de coma flotante IEEE 754 sin pérdida de precisión": https://en.wikipedia.org/wiki/Single-precision_floating-point_format

 0
Author: Kobus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-02 09:54:43

Prueba esto:

select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
 -1
Author: Vipin J S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-20 12:48:23

Prueba esto:

select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
 -1
Author: kierzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-07 22:55:53