Stack Overflow en español Asked by Luca Caña on December 22, 2021
Soy nuevo usando el SQL server, pero necesito sacar, en un campo en donde tengo números decimales, en la cual tengo que visualizar solamente los decimales que superen los 6 caracteres después de la coma.
SELECT *,
Decimales = CASE Charindex('.', Conversion)
WHEN 0 THEN 0
else
Len (
Cast(
Cast(
Reverse(CONVERT(VARCHAR(50), Conversion, 128)) AS FLOAT
) AS BIGINT
)
)
END
FROM CONVERSION_PRODUCTOS
Codigo_Producto Unidad_1 Unidad_2 Conversion
00012031 DI BU 0,08333
00012031 UN BU 0,0119
00013070 BU BU 1
00013070 DI BU 1
00013070 UN BU 1
0003 BU BU 1
0003 DI BU 0,05
Ejemplo: quiero que se visualice solo aquellas conversiones que tengan el decimal mayor a 4 caracteres osea después de la coma por ejemplo 0,08333 este seria el único que cumpliría la condición.
Puedes valerte del siguiente truco matemático.
Supongamos que quieres solo aquellos números que tienen dígitos significativos más allá del 4to decimal.
Según tu ejemplo:
12345 <- número de decimal
0.08333
0.01190
^^
||--- solamente si hay dígitos significativos (no ceros) a partir de esta posición
|---- hastá acá no nos interesa
Para lograr esto, podemos multiplicar un número por la potencia de 10 para correr el punto decimal a la derecha y tomar solamente aquellos números a los que aún les ha quedado una parte decimal, por ejemplo:
0.08333 * 10^4 = 0.08333 * 10000 = 00833.3 <- debemos quedarnos con este, que tiene 0.3
0.01190 * 10^4 = 0.01190 * 10000 = 00119.0 <- y descartar este, que queda con 0
En SQL Server podemos hacer esto valiéndonos de la función power()
que nos devuelve la potencia de un número, y de la resta del número menos el entero del mismo número para obtener la parte decimal ya que SQL Server no tiene una función que nos devuelva la parte decimal de un número.
Es decir, para obtener ese 0.3
, haríamos 833.3 - 833
.
En SQL, luciría algo así:
select *
from conversion_productos
where conversion * power(10, @num_decimales) - floor(conversion * power(10, @num_decimales)) > 0
Donde @num_decimales
tiene la cantidad de decimales que te interesa discriminar. Puedes declarar la variable, para hacerlo dinámico, por ejemplo:
declare @num_decimales int;
set @num_decimales = 4;
O directamente sustituir el valor:
power(10, 4)
Con 4 decimales, la consulta a mi me devuelve:
Codigo_Producto Unidad_1 Unidad_2 Conversion
--------------- -------- -------- ---------------------------------------
00012031 DI BU 0.08333
(1 row affected)
Answered by jachguate on December 22, 2021
A manera de guía (no tengo SQL Server para probarlo); no identifico el nombre del campo que contiene el valor donde tienes los numeros decimales para efectos del presente le llamare miDecimal
; te sugiero lo siguiente:
En un campo
SELECT
CASE
WHEN ((miDecimal*100000) - FLOOR(miDecimal*100000))>0 THEN
miDecimal /* Devuelve el valor */
ELSE
NULL /* No devuelve el valor; asignamos NULL como valor */
END miAlias
FROM
CONVERSION_PRODUCTOS
Como condición
SELECT [TUS COLUMNAS QUE DEVOLVERAS]
FROM
CONVERSION_PRODUCTOS
WHERE
((miDecimal*100000) - FLOOR(miDecimal*100000))>0
lo que se hace es multiplicar el valor por 10,000.00 con ello por ejemplo tendrías para cada valor la parte miDecimal*100000
para 1.0 seria 100000.0; 1.00051 seria 100051.0 y 3.123456 seria 312345.6 (claro entre otros) en el WHERE ((miDecimal*100000) - FLOOR(miDecimal*100000))>0
llamenos a (miDecimal*100000)
la parte 1 y a FLOOR(miDecimal*100000)
la parte 2; la parte 1 será siempre mayor o igual a la parte 2 por tanto el WHERE
evaluaria para cada los valores antes mencionado:
Para 1.0
((miDecimal*100000) - FLOOR(miDecimal*100000))>0
=> ((1.0*100000) - FLOOR(1.0*100000))>0
=> ((100000.0) - FLOOR(100000.0))>0
=> ((100000.0) - (100000.0))>0
=> (0)>0
.
Para 1.00051
((miDecimal*100000) - FLOOR(miDecimal*100000))>0
=> ((1.00051*100000) - FLOOR(1.00051*100000))>0
=> ((100051.0) - FLOOR(100051.0))>0
=> ((100051.0) - (100051.0))>0
=> (0)>0
.
Para 1.00051
((miDecimal*100000) - FLOOR(miDecimal*100000))>0
=> ((1.00051*100000) - FLOOR(1.00051*100000))>0
=> ((100051.0) - FLOOR(100051.0))>0
=> ((100051.0) - (100051.0))>0
=> (0)>0
.
Cabe mencionar, que lo anterior sirve para números positivos; si se puede dar que sean número negativos cambia miDecimal
por Abs(miDecimal)
en cada parte .
Answered by RobertoLeOr on December 22, 2021
Yo haría lo siguiente:
FLOOR()
para obtener la parte entera.varchar
con la función CONVERT()0.
seguido de todos los decimales.En vista de que no incluiste datos de prueba en tu pregunta, hice un ejemplo con el número Pi
que en SQL Server se obtiene con la función PI() y sabemos que tiene más de 6 decimales.
La intención de este código es comprobar de forma rápida la sintaxis y funcionamiento de mi propuesta.
SELECT PI() as Numero,
CONVERT(varchar(50), Pi() - FLOOR(Pi()), 128) as ParteDecimal
WHERE LEN(CONVERT(varchar(50), Pi() - FLOOR(Pi()), 128)) > 8
De acuerdo al conjunto de datos publicado en la pregunta, la consulta quedaría de la siguiente manera
SELECT Codigo_Producto, Unidad_1, Unidad_2, Conversion
FROM CONVERSION_PRODUCTOS
WHERE LEN(CONVERT(varchar(20), Conversion - FLOOR(Conversion), 128)) > 6;
Nota:
No está clara la cantidad de decimales a filtrar entre 6 o 4. Tomando en cuenta el resultado esperado, la selección debería ser todos los registros que tengan más de 4 decimales. El número con el que se compara es 6 porque el resultado de la conversión queda con 0.
al principio, es decir 2 caracteres más.
Answered by Pablo Gutiérrez on December 22, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP