Соответствующий тип данных для хранения процентных значений?

Ответы:

132

Предполагая, что ваши проценты имеют два десятичных знака, тип данных, которые вы используете, зависит от того, как вы планируете хранить свои проценты. Если вы собираетесь хранить их дробный эквивалент (например, 100,00% хранится как 1,0000), я бы сохранил данные в decimal(5,4)типе данных с CHECKограничением, которое гарантирует, что значения никогда не превышают 1,0000 (при условии, что это ограничение) и никогда не опускаются ниже 0 (при условии, что это пол). Если вы собираетесь сохранить их номинальную стоимость (например, 100,00% хранится как 100,00), то вы должны использовать decimal(5,2)с соответствующим CHECKограничением. В сочетании с хорошим именем столбца он дает понять другим разработчикам, что это за данные и как они хранятся в столбце.

Томас
источник
12
Разве это не должно быть decimal(5,2)где 2 обозначает количество цифр после десятичного разделителя?
Boris Callens
2
@BorisCallens - Не могу поверить, что скучал по этому поводу все эти годы. Да, это опечатка. decimal(5,2)это то, что должно быть зафиксировано проверочным ограничением.
Thomas
4
Я предполагаю, что это изначально было decimal(5,4)и было изменено на decimal(5,2)после вышеприведенного комментария ... Я думаю, что это decimal(5,4)было бы лучшее определение - то есть вы хотите сохранить от 0 до 1 с двумя десятичными знаками, а не от 0 до 100. Причина в том, что процентное соотношение не соответствует 100; Таким образом, 100% равно 100/100, что составляет 1. В большинстве случаев такой подход имеет смысл (например 100% * 100% = 100%, нет 10000%; 1 * 1 = 1).
JohnLBevan
4
@JohnLBevan - он тратит на то, как они хранятся. Если значения будут храниться в том виде, в каком они отображаются (например 100.00), вам необходимо decimal(5,2). Если значения будут храниться в виде дробей (например 1.0000), тогда вам нужно decimal(5,4). Буду обновлять пост.
Thomas
Кто-нибудь может объяснить, зачем вам 4 знака после запятой? Вы не можете использовать 2? Например .91 === 91% или 1.00 === 100%. Я реализую это сейчас и удивляюсь выигрышу с 4 местами. Что-то вроде Pct decimal (10, 2) CHECK (Pct> =. 01 AND Pct <= 1). Заранее спасибо.
Пн
31
  • Держи как decimal.
  • Добавьте проверочные ограничения, если вы хотите ограничить диапазон (например, от 0 до 100%; в некоторых случаях могут быть веские причины для выхода за пределы 100% или, возможно, даже в отрицательные значения).
  • Рассматривайте значение 1 как 100%, 0,5 как 50% и т. Д. Это позволит любым математическим операциям функционировать должным образом (т. Е. Вместо использования значения 100 как 100%).
  • При необходимости измените точность и масштаб (это два значения в скобках columnName decimal(precision, scale). Точность говорит об общем количестве цифр, которое может содержаться в числе, масштаб говорит, сколько из них стоит после десятичного разряда, decimal(3,2)а также число, которое может быть представлено как #.##; decimal(5,3)было бы ##.###.
  • decimalи numericпо сути одно и то же. Однако decimalон соответствует стандарту ANSI, поэтому всегда используйте его, если не указано иное (например, стандарты кодирования вашей компании).

Примеры сценариев

  • Для вашего случая (от 0,00% до 100,00%) вам нужно decimal(5,4).
  • Для наиболее распространенного случая (от 0% до 100%) вам нужно decimal(3,2).
  • В обоих случаях проверочные ограничения будут одинаковыми.

Пример:

if object_id('Demo') is null
create table Demo
    (
        Id bigint not null identity(1,1) constraint pk_Demo primary key
        , Name nvarchar(256) not null constraint uk_Demo unique 
        , SomePercentValue decimal(3,2) constraint chk_Demo_SomePercentValue check (SomePercentValue between 0 and 1)
        , SomePrecisionPercentValue decimal(5,2) constraint chk_Demo_SomePrecisionPercentValue check (SomePrecisionPercentValue between 0 and 1)
    )

Дальнейшее чтение:

ДжонЛБеван
источник
4

Я согласен с Томасом и выбрал бы решение DECIMAL (5,4) по крайней мере для приложений WPF.

Взгляните на строку числового формата MSDN, чтобы узнать, почему: http://msdn.microsoft.com/en-us/library/dwhawy9k#PFormatString

Спецификатор формата процента («P») умножает число на 100 и преобразует его в строку, представляющую процент.

Тогда вы сможете использовать это в своем коде XAML:

DataFormatString="{}{0:P}"
Pjehan
источник
2

Если ваш уровень точности составляет 2 десятичных разряда, то "smallint" обработает это в наименьшем пространстве (2 байта). Вы сохраняете процент, умноженный на 100.

РЕДАКТИРОВАТЬ: десятичный тип, вероятно, лучше подходит. Тогда вам не нужно масштабировать вручную. На каждое значение требуется 5 байтов.

mdma
источник
Microsoft сломала так много ссылок ...
pcnate
0

Используйте числовые (n, n), где n имеет разрешение, достаточное для округления до 1,00. Например:

declare @discount numeric(9,9)
    , @quantity int
select @discount = 0.999999999
    , @quantity = 10000

select convert(money, @discount * @quantity)
user2202942
источник
3
Этот вопрос получил довольно высокий рейтинг принятый ответ более трех лет назад. Если вы ищете ответы на старые вопросы, обратитесь сюда: stackoverflow.com/unansrupted
valverij