Відповідний тип даних для зберігання відсоткових значень?


Відповіді:


132

Якщо припустити два знаки після коми у відсотках, тип даних, який ви використовуєте, залежить від того, як ви плануєте зберігати свої відсотки. Якщо ви збираєтеся зберігати їх дробовий еквівалент (наприклад, 100%, що зберігається як 1.0000), я б зберігав дані у decimal(5,4)типі даних з CHECKобмеженням, яке гарантує, що значення ніколи не перевищують 1.0000 (якщо вважати, що це обмеження) і ніколи не опускаються нижче 0 (припустимо, що це слово). Якщо ви збираєтеся зберігати їх номінал (наприклад, 100% зберігається як 100,00), тоді вам слід скористатися decimal(5,2)відповідним CHECKобмеженням. У поєднанні з хорошою назвою стовпця він дає зрозуміти іншим розробникам, що це за дані, і як вони зберігаються в стовпці.


12
Чи не повинно бути decimal(5,2)там, де 2 позначає кількість цифр після десяткового роздільника?
Борис Калленс

2
@BorisCallens - Не можу повірити, що я пропустив це всі ці роки. Так, це друкарня. decimal(5,2)це те, що повинно бути захоплено з обмеженням чека.
Томас

4
Я припускаю, що це спочатку було decimal(5,4)і було змінено decimal(5,2)після вищезазначеного коментаря ... Я думаю, decimal(5,4)було б кращим визначенням - тобто ви хочете зберігати від 0 до 1 з 2 десятковими знаками, а не від 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). Оновить публікацію.
Томас

Хтось може пояснити, навіщо вам потрібно 4 десяткових знаки? Не можете використовувати 2? Як .91 === 91% або 1,00 === 100%. Я реалізую це зараз і цікавився виграшем з 4-х місць. Щось на зразок Pct десяткових (10, 2) ПЕРЕВІРИТЬ (Pct> =. 01 І Pct <= 1). Заздалегідь спасибі.
MH

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}"

2

Якщо два десяткових знаки - це ваш рівень точності, то "smallint" впорається з цим у найменшому просторі (2-байт). Ви зберігаєте відсотки, помножені на 100.

EDIT: Десятковий тип - це, мабуть, краща відповідність. Тоді вам не потрібно вручну масштабувати. Це займає 5 байт за значення.


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)

3
Це питання має досить високу оцінку прийнятої відповіді понад три роки тому. Якщо ви шукаєте старі питання відповісти, будь ласка , зверніться сюди: stackoverflow.com/unanswered
valverij
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.