TransWikia.com

filtrar la cantidad de caracteres que tiene un cierto decimal en sql server

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.

3 Answers

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:

  1. Para obtener sólo la parte decimal, al número le resto su parte entera. Se puede utilizar la función FLOOR() para obtener la parte entera.
  2. Al resulado anterior lo convierto a varchar con la función CONVERT()
  3. Si la longitud del texto resultado es mayor que 8, entonces contiene más de 6 decimales. La razón por la que lo comparo con 8 es porque el texto comienza por 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

Actualización

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP