2012-01-23 8 views
11

En MS SQL, necesito un enfoque para determinar la escala más grande utilizada por las filas para una determinada columna decimal.Determine la escala decimal MAX utilizada en una columna

Por ejemplo, Col1 Decimal (19,8) tiene una escala de 8, pero necesito saber si realmente se están usando los 8, o si solo se están utilizando 5, 6 o 7.

datos de ejemplo:

123.12345000 
321.000 
5255.12340000 
5244.12345000 

Por los datos anteriores, que había necesidad de que la consulta sea de vuelta 5, o 123.12345000 o 5.244,12345000.

No me preocupa el rendimiento, estoy seguro de que una exploración de tabla completa estará en orden, solo necesito ejecutar la consulta una vez.

Respuesta

9

No es bonita, pero creo que debe hacer el truco:

-- Find the first non-zero character in the reversed string... 
-- And then subtract from the scale of the decimal + 1. 
SELECT 9 - PATINDEX('%[1-9]%', REVERSE(Col1)) 
+0

No es bonita, pero brillante. Funciona de maravilla. Acaba de agregar el MAX() y filtró 0.00000000. Agregar MAX() me dio: SELECT MAX (9 - PATINDEX ('% [1-9]%', REVERSE (Col1))) –

6

me gusta @Michael Fredrickson's answer mejor y sólo estoy publicando esto como una alternativa para casos específicos en los que la escala real es desconocida, pero es cierto que no hay más de 18:

SELECT LEN(CAST(CAST(REVERSE(Col1) AS float) AS bigint)) 

Tenga en cuenta que, aunque hay dos REPARTO explícita llama aquí, la consulta en realidad realiza dos conversiones más implícitos:

  1. Como el argumento de REVERSE, Col1 se convierte en una cadena.

  2. El bigint se emite como una cadena antes de ser utilizado como argumento de LEN.

+0

+1 Para no necesitar saber la escala ... –

+0

Ayudó a encontrar una solución para este: http://stackoverflow.com/a/14715318/114029 Tuve que ir aún más lejos y usé la publicación de este tipo para llegar: http://connectsql.blogspot.com.br/2011/04/normal-0 -microsoftinternetexplorer4.html Es interesante cómo se llega a una solución basada en información dispersa aquí y allá ...: D –

0
SELECT 
    MAX(CHAR_LENGTH(
     SUBSTRING(column_name::text FROM '\.(\d*?)0*$') 
    )) AS max_scale 
FROM table_name; 

*? es la versión no codicioso de *, de modo \d*? capturas todos los dígitos después del punto decimal excepto ceros a la derecha.

El patrón contiene un par de paréntesis, por lo que se devuelve la parte del texto que coincide con la primera subexpresión entre paréntesis (es decir, \d*?).

Referencias:

0

Nota esto escanear toda la tabla:

SELECT TOP 1 [Col1] 
FROM [Table] 
ORDER BY LEN(PARSENAME(CAST([Col1] AS VARCHAR(40)), 1)) DESC 
Cuestiones relacionadas