uso - Redondear a n cifras significativas en SQL
sql redondear hacia arriba (4)
Me gustaría poder redondear un número a n cifras significativas en SQL. Asi que:
123.456 rounded to 2sf would give 120
0.00123 rounded to 2sf would give 0.0012
Soy consciente de la función ROUND (), que se redondea a n lugares decimales en lugar de cifras significativas.
Adapté la respuesta más popular de Brann a MySQL para aquellos que se ven como yo.
CREATE FUNCTION `sfround`(num FLOAT, sf INT) # creates the function
RETURNS float # defines output type
DETERMINISTIC # given input, will return same output
BEGIN
DECLARE r FLOAT; # make a variable called r, defined as a float
IF( num IS NULL OR num = 0) THEN # ensure the number exists, and isn''t 0
SET r = num; # if it is; leave alone
ELSE
SET r = ROUND(num, sf - 1 - FLOOR(LOG10(ABS(num))));
/* see below*/
END IF;
RETURN (r);
END
/ * Sentí demasiado tiempo para poner en comentario * /
REDONDO (num, sf - 1 - PISO (LOG10 (ABS (num))))
- La parte que realiza el trabajo: utiliza la función REDONDA en el número como normal, pero se calcula la longitud a redondear.
- ABS asegura positivo
- LOG10 obtiene el número de dígitos mayor que 0 en el número
- FLOOR obtiene el mayor entero más pequeño que el número resultante
- Así que siempre se redondea y da un entero.
- sf - 1 - FLOOR (...) da un número negativo
funciona porque ROUND (num, -ve num) se redondea a la izquierda del punto decimal
Para solo uno, ROUND (123.456, -1) y ROUND (0.00123,4) devuelven las respuestas solicitadas ((120, 0.0012)
Creo que lo he conseguido.
CREATE FUNCTION RoundSigFig(@Number float, @Figures int)
RETURNS float
AS
BEGIN
DECLARE @Answer float;
SET @Answer = (
SELECT
CASE WHEN intPower IS NULL THEN 0
ELSE FLOOR(fltNumber * POWER(CAST(10 AS float), intPower) + 0.5)
* POWER(CAST(10 AS float), -intPower)
END AS ans
FROM (
SELECT
@Number AS fltNumber,
CASE WHEN @Number > 0
THEN -((CEILING(LOG10(@Number)) - @Figures))
WHEN @Number < 0
THEN -((FLOOR(LOG10(@Number)) - @Figures))
ELSE NULL END AS intPower
) t
);
RETURN @Answer;
END
Podrías dividir por 100 antes de redondear y luego multiplicar por 100 ...
select round(@number,@sf-1- floor(log10(abs(@number))))
debería hacer el truco!
Probado con éxito en sus dos ejemplos.
Editar: Llamar a esta función en @ número = 0 no funcionará. Debe agregar una prueba para esto antes de usar este código.
create function sfround(@number float, @sf int) returns float as
begin
declare @r float
select @r = case when @number = 0 then 0 else round(@number ,@sf -1-floor(log10(abs(@number )))) end
return (@r)
end