Определите десятичную шкалу MAX, используемую в столбце

В MS SQL мне нужен подход, чтобы определить наибольший масштаб, используемый строками для определенного десятичного столбца.

Например, Col1 Decimal (19,8) имеет шкалу из 8, но мне нужно знать, используются ли все 8 или используются только 5, 6 или 7.

Пример данных:

123.12345000
321.43210000
5255.12340000
5244.12345000

Для приведенных выше данных мне понадобится запрос для возврата 5 или 123.12345000 или 5244.12345000.

Меня не интересует производительность, я уверен, что полное сканирование таблицы будет в порядке, мне просто нужно запустить запрос один раз.

Ответ 1

Не очень, но я думаю, что он должен сделать трюк:

-- 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))

Ответ 2

Мне нравится @Майкл Фредриксон ответить лучше, и я публикую это только как альтернативу для конкретных случаев, когда фактический масштаб неизвестен, но наверняка будет не более 18

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

Обратите внимание, что хотя здесь есть два явных вызова CAST, запрос фактически выполняет еще два неявных преобразования:

  • Как аргумент REVERSE, Col1 преобразуется в строку.

  • bigint передается как строка перед использованием в качестве аргумента LEN.

Ответ 3

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

*? - это не жадная версия *, поэтому \d*? ловит все цифры после десятичной точки, кроме конечных нулей.

Шаблон содержит пару круглых скобок, поэтому возвращается часть текста, совпадающая с первым подвыражением в скобках (то есть \d*?).

Литература:

Ответ 4

Обратите внимание, что это сканирует всю таблицу:

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