Ответ 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))
В MS SQL мне нужен подход, чтобы определить наибольший масштаб, используемый строками для определенного десятичного столбца.
Например, Col1 Decimal (19,8) имеет шкалу из 8, но мне нужно знать, используются ли все 8 или используются только 5, 6 или 7.
Пример данных:
123.12345000
321.43210000
5255.12340000
5244.12345000
Для приведенных выше данных мне понадобится запрос для возврата 5 или 123.12345000 или 5244.12345000.
Меня не интересует производительность, я уверен, что полное сканирование таблицы будет в порядке, мне просто нужно запустить запрос один раз.
Не очень, но я думаю, что он должен сделать трюк:
-- 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))
Мне нравится @Майкл Фредриксон ответить лучше, и я публикую это только как альтернативу для конкретных случаев, когда фактический масштаб неизвестен, но наверняка будет не более 18
SELECT LEN(CAST(CAST(REVERSE(Col1) AS float) AS bigint))
Обратите внимание, что хотя здесь есть два явных вызова CAST, запрос фактически выполняет еще два неявных преобразования:
Как аргумент REVERSE, Col1
преобразуется в строку.
bigint
передается как строка перед использованием в качестве аргумента LEN.
SELECT
MAX(CHAR_LENGTH(
SUBSTRING(column_name::text FROM '\.(\d*?)0*$')
)) AS max_scale
FROM table_name;
*?
- это не жадная версия *
, поэтому \d*?
ловит все цифры после десятичной точки, кроме конечных нулей.
Шаблон содержит пару круглых скобок, поэтому возвращается часть текста, совпадающая с первым подвыражением в скобках (то есть \d*?
).
Литература:
Обратите внимание, что это сканирует всю таблицу:
SELECT TOP 1 [Col1]
FROM [Table]
ORDER BY LEN(PARSENAME(CAST([Col1] AS VARCHAR(40)), 1)) DESC