Tengo una columna, DECIMAL(9,6)
es decir, admite valores como 999,123456.
Pero cuando inserto datos como 123,4567 se convierte en 123,456700
¿Cómo eliminar esos ceros?
Tengo una columna, DECIMAL(9,6)
es decir, admite valores como 999,123456.
Pero cuando inserto datos como 123,4567 se convierte en 123,456700
¿Cómo eliminar esos ceros?
Respuestas:
A decimal(9,6)
almacena 6 dígitos en el lado derecho de la coma. Mostrar ceros finales o no es una decisión de formato, generalmente implementada en el lado del cliente.
Pero dado que SSMS formatea float
sin ceros finales, puede eliminar ceros finales al convertir el decimal
a a float
:
select
cast(123.4567 as DECIMAL(9,6))
, cast(cast(123.4567 as DECIMAL(9,6)) as float)
huellas dactilares:
123.456700 123,4567
(Mi separador decimal es una coma, pero SSMS formatea decimal con un punto. Aparentemente un problema conocido ).
Puede utilizar la FORMAT()
función (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 más grande ( g8
o más grande 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, según la documentación :
FORMAT se basa en la presencia de .NET Framework Common Language Runtime (CLR). Esta función no será remota ya que depende de la presencia del CLR. La comunicación remota de una función que requiere CLR provocaría un error en el servidor remoto.
También funciona en SqlAzure.
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
Estaba reacio a lanzar para flotar debido a la posibilidad de que haya más dígitos en mi decimal de los que flota puede representar
FORMAT
cuando se usa con una cadena de formato .net estándar 'g8' devuelve la notación científica en casos de decimales muy pequeños (por ejemplo, 1e-08) que tampoco era adecuada
El uso de 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 al final, de modo 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. es
Por supuesto, esta es la práctica desalentadora de tener la capa de datos formateando (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: /)
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
huellas dactilares:
2.55
Cast(20.5500 as Decimal(6,2))
Deberías hacerlo.
Prueba esto :
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
Da 20,55
0.000
convirtió en un problema menor detectado .
. aquí está la solución SELECT REPLACE(RTRIM(REPLACE(20.5500, "0", " ")), " ", "0")
para recortar solo los ceros finales
Tuve un problema similar, pero también se me pidió que eliminara el punto decimal donde no había decimal, aquí estaba mi solución que divide el decimal en sus componentes y basa el número de caracteres que toma de la cadena del punto decimal en la longitud de el componente de fracción (sin usar CASE). Para hacer las cosas aún más interesantes, mi número se almacenó 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 las respuestas anteriores.
La mejor manera es NO convertir a FLOAT o MONEY antes de convertir debido a la posibilidad de pérdida de precisión. Entonces, 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)
sp_
para procedimientos almacenados, fn_
funciones, tbl
tablas, etc. en ... esto no es un requisito, pero son las mejores prácticas para organizar nuestras bases de datos.
Tuve un problema similar, necesitaba recortar los ceros finales de números como xx0000,x00000,xxx000
Solía:
select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename
Código es el nombre del campo con el número que se va a recortar. Espero que esto ayude a alguien más.
Otra opción...
No sé qué tan eficiente es esto, pero parece funcionar y no pasa por flotación:
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
Que necesitaba para eliminar los ceros finales en mis decimales por lo que podría generar una cadena de una cierta longitud, con sólo conducen ceros
(por ejemplo, necesitaba generar 14 caracteres para que 142.023400 se convirtiera en 000000142.0234),
Usé 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 luego obtener mis ceros iniciales, podría replicar el número correcto de ceros en función de la longitud de lo anterior y concatenar esto al frente de lo anterior)
Espero que esto ayude a alguien.
es posible eliminar los ceros iniciales y finales en TSQL
Conviértalo en una cadena usando la función STR TSQL si no es una cadena, entonces
Quitar ceros iniciales y finales
SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
Más información en el foro .
REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(REPLACE(X,'0',' ')),' ','0'),'.',' ')),' ','.')
¿Qué tal esto? Suponiendo que los datos que ingresan a su función son @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
Entiendo que esta es una publicación antigua, 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
prueba esto.
select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
La forma más sencilla es CAST el valor como FLOAT y luego a un tipo de datos de cadena.
CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
Prueba esto:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
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 FORMAT por algún motivo, lo siguiente funciona.
Además, muchas de las soluciones no funcionaron si el número era menor que 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.
Prueba esto:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
999999
, el OP solicita eliminar los ceros finales.
Una columna DECIMAL (9,6) se convertirá en flotante sin pérdida de precisión, por lo que CAST (... AS float) funcionará.
@HLGEM: decir que flotar es una mala elección para almacenar números y que "Nunca usar flotador" no es correcto; solo tiene que conocer sus números, por ejemplo, las mediciones de temperatura irían bien como flotadores.
@abatishchev y @japongskie: los prefijos delante de los procesos y funciones almacenados en SQL siguen siendo una buena idea, si no son necesarios; los enlaces que mencionaste solo indican que no uses el prefijo "sp_" para los procedimientos almacenados que no debes usar, otros prefijos están bien, por ejemplo, "usp_" o "spBob_"
Referencia: "Todos los números enteros con 6 o menos dígitos decimales significativos se pueden convertir a un valor de punto flotante IEEE 754 sin pérdida de precisión": https://en.wikipedia.org/wiki/Single-precision_floating-point_format