Чи слід вибрати типи даних MONEY або DECIMAL (x, y) у SQL Server?


442

Мені цікаво, чи існує реальна різниця між moneyтипом даних та чимось подібним decimal(19,4)(я вважаю, що гроші використовують внутрішньо).

Мені відомо, що moneyхарактерно для SQL Server. Я хочу знати, чи є вагома причина обрати одну над іншою; більшість зразків SQL Server (наприклад, база даних AdventureWorks) використовують, moneyа не decimalдля таких речей, як інформація про ціни.

Чи варто просто продовжувати використовувати тип даних грошей, чи є користь використовувати десятковий натомість? Гроші набирають менше символів, але це не поважна причина :)


12
DECIMAL(19, 4) це популярний вибір, перевірте це, також перевірте тут Формати світової валюти, щоб визначити, скільки десяткових знаків використовувати, надію, допоможе.
shaijut

Мені було цікаво, чому тип даних грошей має 4 десяткові знаки .., а не 2. тобто 100 центів у доларі, тому потрібно лише 2 знаки після коми? Для зберігання записів грошей менше ніж 9999,99 доларів я збирався використати тип даних із десятковою (6,2). Мене не хвилюють обчислення поділу чи множення, просто зберігання та підсумовування ..
Аллан Ф

Відповіді:


326

Ніколи не слід використовувати гроші. Це не точно, і це чистий сміття; завжди використовувати десятковий / числовий.

Запустіть це, щоб побачити, що я маю на увазі:

DECLARE
    @mon1 MONEY,
    @mon2 MONEY,
    @mon3 MONEY,
    @mon4 MONEY,
    @num1 DECIMAL(19,4),
    @num2 DECIMAL(19,4),
    @num3 DECIMAL(19,4),
    @num4 DECIMAL(19,4)

    SELECT
    @mon1 = 100, @mon2 = 339, @mon3 = 10000,
    @num1 = 100, @num2 = 339, @num3 = 10000

    SET @mon4 = @mon1/@mon2*@mon3
    SET @num4 = @num1/@num2*@num3

    SELECT @mon4 AS moneyresult,
    @num4 AS numericresult

Вихід: 2949.0000 2949.8525

Деякі з людей, які сказали, що ви не ділите гроші на гроші:

Ось один із моїх запитів щодо обчислення кореляцій, і зміна цих грошей дає неправильні результати.

select t1.index_id,t2.index_id,(avg(t1.monret*t2.monret)
    -(avg(t1.monret) * avg(t2.monret)))
            /((sqrt(avg(square(t1.monret)) - square(avg(t1.monret))))
            *(sqrt(avg(square(t2.monret)) - square(avg(t2.monret))))),
current_timestamp,@MaxDate
            from Table1 t1  join Table1 t2  on t1.Date = traDate
            group by t1.index_id,t2.index_id

61
"Ніколи" - сильне слово. "Гроші" корисні для передачі результатів для цього типу для відображення користувачеві в залежності від культури, але ви маєте рацію, що це дуже погано використовувати для самих розрахунків.
Joel Coehoorn

36
Ваш приклад не має сенсу, оскільки ніхто ніколи не примножить два об’єкти грошей типу. Якщо ви хочете довести свою точку, вам потрібно порівняти множення грошей на десяткову та множення десяткової на десяткову.
Брайан

27
.. але все ще дивно, чому гроші * гроші не мали б точності грошей.
Навчання

4
@ Навчання: у нього є точність грошей. Однак ви все одно стикаєтеся з помилками округлення, які можуть накопичуватися з часом. Десятковий тип не використовує двійкову арифметику: він гарантує, що він отримає той самий базовий 10 результат, який ви зробили б на папері.
Joel Coehoorn

55
Помноження та ділення moneyна moneyсторону, ця "ілюстрація" є маніпулятивною. Це документально підтверджений факт, що moneyмає фіксовану і дуже обмежену точність. У таких випадках слід спочатку помножити, а потім розділити. Змініть порядок операторів у цьому прикладі, і ви отримаєте однакові результати. По moneyсуті це 64-бітний інт, і якби ви мали справу з інтами, ви помножилися б перед поділом.
Андрій М

272

SQLMenace сказав, що гроші є неточними. Але ви не примножуєте / не ділите гроші на гроші! Скільки коштує 3 долари 50 центів? 150 доларових центів? Ви перемножуєте / ділите гроші на скаляри, які повинні бути десяткові.

DECLARE
@mon1 MONEY,
@mon4 MONEY,
@num1 DECIMAL(19,4),
@num2 DECIMAL(19,4),
@num3 DECIMAL(19,4),
@num4 DECIMAL(19,4)

SELECT
@mon1 = 100,
@num1 = 100, @num2 = 339, @num3 = 10000

SET @mon4 = @mon1/@num2*@num3
SET @num4 = @num1/@num2*@num3

SELECT @mon4 AS moneyresult,
@num4 AS numericresult

Результати в правильному результаті:

грошірезультат числовийрезультат
--------------------- ----------------------------- ----------
2949.8525 2949.8525

moneyдобре, доки вам не потрібно більше 4-х десяткових цифр, і ви переконайтеся, що ваші скаляри - які не представляють гроші - є decimals.


57
скільки монет за 1 цент може отримати банкнота? відповідь на це вимагає грошей / грошей.
Навчання

48
@ Навчання в цьому випадку результат - не гроші, а поплавок. (Основний розмірний аналіз.)
Річард

11
@Learning: Ви запитуєте базу даних, скільки центів у доларі багато? У будь-якому випадку це поверне правильний результат. Його проблема полягала в тому, що гроші / гроші були точні лише до чотирьох цифр (це було 0,2949), потім, помноживши на 10000, вони стали 2949,0000.
конфігуратор

26
@mson Він правильний і не висуває особистої критики, як ви робили на основі зауваження в одному рядку, це не корисно. Якщо він не ділиться на 0,01 долара, а замість 0,01, то результат становить 100 доларів замість 100. Там долари 100 центів, а не 100 центів. Одиниці важливі! Там, безумовно, є велике місце для дайвінгу і, можливо, примноження грошей на гроші.
andrewb

19
Якщо я хочу витратити 1000 доларів на придбання акцій за ціною 36 доларів, це не є законним використанням money / money? Відповідь - цілі одиниці, не прикріплені знаком долара, що правильно! Це цілком розумний сценарій, який дозволяє припустити, що через такі дивні випадкові випадки кращого moneyтипу даних не можна використовувати, оскільки результат завжди скорочується назад, щоб відповідати moneyзамість того, щоб дотримуватися звичайних правил точності та масштабу. Що робити, якщо ви хочете обчислити стандартне відхилення набору moneyзначень? Так, Sqrt(Sum(money * money))(спрощено) насправді має сенс.
ЕрікЕ

59

Все небезпечно, якщо ви не знаєте, що робите

Навіть десяткові високоточні типи не можуть врятувати день:

declare @num1 numeric(38,22)
declare @num2 numeric(38,22)
set @num1 = .0000006
set @num2 = 1.0
select @num1 * @num2 * 1000000

1.000000 <- Має бути 0,6000000


Ці moneyтипи є цілими числами

Текстові зображення smallmoneyі decimal(10,4)можуть виглядати однаково, але це не робить їх взаємозамінними. Чи ти скучиш, коли бачиш, що дати зберігаються як varchar(10)? Це те саме.

За лаштунками, money/ smallmoneyє лише a bigint/ int Десяткова крапка в текстовому поданні moneyє візуальним пухом, як і тире в дату "yyyy-mm-dd". SQL насправді не зберігає їх всередині.

Щодо decimalvs money, виберіть те, що відповідає вашим потребам. Ці moneyтипи існують, тому що зберігання облікових значень як цілих кратних 1/10000-ої одиниці дуже поширене. Крім того, якщо ви маєте справу з фактичними грошима та розрахунками, що перевищують просте додавання та віднімання, ви не повинні робити цього на рівні бази даних! Зробіть це на рівні програми з бібліотекою, яка підтримує заокруглення Banker (IEEE 754)


1
Чи можете ви пояснити, що сталося на цьому прикладі?
Сергій Попов

4
Масштабний перелив. У малих масштабах числовий (a, b) * числовий (c, d) дає числовий (a-b + c-d + 1, max (b, d)). Однак якщо (a + b + c + d)> 38, SQL обмежує масштаб, грабуючи точність зі сторони дробу, щоб зменшити цілу сторону, викликаючи помилку округлення.
Анон

Усі чисельні обчислення сприйнятливі до втрати точності через масштабування: замість обчислення виберіть 1000000 * @ num1 * @ num2
Мітч Пшеничний

Приклад Анона - версія та база даних. але справа бути обережною справедлива. у sqlanywhere версії 1.1, приклад дійсно дає 0,600000. (Я знаю, ми тут говоримо про ms sql). Інший пункт про відсутність типу грошей в іншій базі даних, є способи виклику десяткових чи числових чисел як гроші, наприклад створення домену.
gg89

3
Я думаю, що це найяскравіша відповідь, тому що ви пояснили не просто помилки, які розповсюджуються, а те, що відбувається насправді за сценою, і чому ГРОШІ існують в першу чергу. Я не впевнений, чому знадобилося 4 роки, щоб отримати цю відповідь, але, можливо, це тому, що тут занадто багато уваги на "проблемі" обчислення, а не стільки на те, на чому і як гроші гроші проти десяткових.
Стів Сетер

44

Я розумію, що WayneM заявив, що знає, що гроші є специфічними для SQL Server. Однак він запитує, чи є якісь причини використовувати гроші над десятковою чи навпаки, і я думаю, що одна очевидна причина все-таки повинна бути вказана, а це використання десяткової означає, що це одна річ, яку потрібно турбуватися, якщо вам коли-небудь доведеться змінити СУБД - що може статися.

Зробіть ваші системи максимально гнучкими!


1
Можливо, але теоретично ви можете оголосити домен з іменем Money в іншій СУБД (що підтримує декларацію доменів).
дебат

Оскільки хтось зараз перетворює базу даних SQL Server в Amazon Redshift, я можу підтвердити, що це справжня проблема. Постарайтеся уникати типів даних, які підпадають під певну платформу бази даних, якщо для їх використання не існують дуже надійні ділові причини.
Натан Гріффітс

@Nathn дав слабку систему Redshift порівняно з PostgreSQL або SQL Server, наприклад, немає dateтипу, я б сказав, що у вас завжди будуть такі проблеми. Вам слід сказати "Не використовуйте застарілі типи, коли база даних вже забезпечує кращі, більш сумісні з типом типи та попереджає про застарілі".
Панайотис Канавос

@PanagiotisKanavos - гроші не застаріли
Martin Smith

@MartinSmith шокував це, оскільки він не може насправді обробляти кошти, такі як BTC у 2017 році. Або розрізняти суми GBP та EUR - навіть якщо вони рухаються в бік паритету: P. У всякому разі, перехід до Redshift вводить багато болю
Панайотіс Kanavos

32

Ну, мені подобається MONEY! Це байт дешевше DECIMAL, а обчислення виконуються швидше, оскільки (під кришками) операції додавання та віднімання по суті є цілими операціями. Приклад @ SQLMenace - який є чудовим попередженням для невідомих - може однаково застосовуватися і до INTegers, де результат буде нульовим. Але це не є причиною не використовувати цілі числа - де це доречно .

Таким чином, це абсолютно "безпечно" і доцільно використовувати, MONEYколи ви маєте справу з цим, MONEYі використовувати його відповідно до математичних правил, які вони дотримуються (так само, як і INTeger).

Було б краще, якби SQL Server сприяв поділу та множенню MONEYs на DECIMALs (або FLOATs?) - можливо, але вони не вирішили цього робити; і вони не вирішили просувати INTегер під FLOATчас їх поділу.

MONEYне має жодних питань щодо точності; щоб DECIMALотримати більший проміжний тип, який використовується під час обчислень, це лише "особливість" використання цього типу (і я не впевнений, наскільки ця "особливість" поширюється).

Щоб відповісти на конкретне запитання, "переконлива причина"? Ну, якщо ви хочете абсолютну продуктивність максимуму в SUM(x)якому xможе бути DECIMALабо MONEY, то MONEYбуде мати перевагу.

Крім того, не забувайте, що це менший двоюрідний брат - SMALLMONEYпросто 4 байти, але він максимум на 214,748.3647- що є досить маленьким для грошей - і так часто не підходить.

Для підтвердження суті використання великих проміжних типів, якщо проміжний явно призначати змінну, DECIMALвиникає та сама проблема:

declare @a decimal(19,4)
declare @b decimal(19,4)
declare @c decimal(19,4)
declare @d decimal(19,4)

select @a = 100, @b = 339, @c = 10000

set @d = @a/@b

set @d = @d*@c

select @d

Виробляє 2950.0000(добре, так що принаймні DECIMALокруглене, а не MONEYусічене - те саме, що і ціле число).


21
MONEYє на один байт менше великого DECIMAL , з точністю до 19 цифр. Однак більшість грошових розрахунків у реальному світі (до 9,99 млн. Доларів США) можуть вміститися в лінійці DECIMAL(9, 2), для якої потрібно всього п'ять байт. Ви можете зберегти розмір, менше турбуватися про помилки округлення та зробити свій код більш портативним.

Хоча @JonofAllTrades є правильним, ви також можете отримати цілі показники, просто скориставшись цілим числом, що містить копійки або центи, і зберегти зайвий байт, що кодує позицію десяткової крапки, і який потрібно перевірити, додаючи десяткові числа разом.
dsz

"Отже, цілком" безпечно "і доцільно використовувати ГРОШІ, коли те, з чим ви маєте справу - це ДЕНЬГІ, і використовувати його відповідно до математичних правил, яким воно слідує", - однак, див. Також відповідь Анона: "Все небезпечно, якщо ви цього не зробите знайте, що ви робите ». Ніколи не можна передбачити, як люди закінчать запитувати систему, яку ви створюєте, найкраще уникати можливості неправильного використання, коли зможете. Мінусний приріст у сховищі IMHO не варто.
Натан Гріффітс

1
Спробуйте зберегти значення Bitcoin. Має 8
десятків

14

Ми щойно зіткнулися з дуже подібною проблемою, і мені зараз дуже важливо +1 за те, що ніколи не використовую гроші, окрім презентації верхнього рівня. У нас є кілька таблиць (фактично ваучер на продаж та рахунок-фактура продажу), кожна з яких містить одне або більше грошових полів з історичних причин, і нам потрібно здійснити пропорційний розрахунок, щоб визначити, яка сума сукупного податку на рахунки відповідає кожному лінія на ваучері продажів. Наш розрахунок є

vat proportion = total invoice vat x (voucher line value / total invoice value)

Це призводить до обчислення грошей в реальному світі / грошей, що спричинює масштабні помилки на частині поділу, яка потім множиться на неправильну пропорцію. Коли ці значення згодом додаються, ми закінчуємо сумою пропорцій чану, які не складаються із загальної величини рахунка-фактури. Якби будь-яке зі значень у дужках було десятковою (я збираюся видати одне з них як таке), пропорція vat була б правильною.

Коли в дужках спочатку це не працювало, я думаю, через більші значення, це ефективно імітувало більш високу шкалу. Ми додали дужки, оскільки спочатку робили множення, що в деяких рідкісних випадках призводить до точності, доступної для обчислення, але це спричинило набагато більш поширену помилку.


8
Але це робиться лише тому, що необізнаний розробник ігнорував правила обчислення ПДВ та задокументовані обмеження грошової точності.
TomTom

1
@TomTom, але точка, на яку ви звертаєтесь щодо можливості неправомірного використання цього типу даних, є аргументом на користь уникнення його використання взагалі.
Натан Гріффітс

@Nathan Ні. Я наголошую, що аргумент, наведений як привід ніколи не використовувати його, є в основному некомпетентним розробником, тому аргумент є хибним.
TomTom

1
@TomTom, на жаль, є багато некомпетентних розробників (як і багато дивовижних) і для мене, якщо я не міг гарантувати, як ці дані будуть запитуватися в майбутньому, і ніхто не збирався робити помилки, описані тут , краще помилитися з боку обережності та використовувати десятковий тип. Однак, прочитавши всі ці відповіді, я можу побачити, що є певні конкретні випадки використання, коли гроші були б оптимальним типом для використання, я просто не використовував би їх, якщо не було для цього дуже хорошого випадку використання (наприклад, стовпець буде лише коли-небудь бути об'єднаним за SUM, масовим завантаженням великої кількості фінансових даних).
Натан Гріффітс

@TomTom це не лише обмеження точності. Внутрішнє представництво також може викликати проблеми. Гроші - це зручність для лову необізнаних розробників, а не чудовий тип, який розробники зловживають. Приклад vat, незалежно від правил його обчислення, очевидно, повинен відлякати неігнорованих розробників, коли вони застосовують конкретне до загального.
Джерард ONeill

12

Як протилежну точку до загальної тяги інших відповідей. Дивіться багато переваг грошей ... Тип даних! у посібнику з реляційного двигуна SQLCAT

Конкретно я зазначив би наступне

Працюючи над впровадженнями клієнтів, ми знайшли цікаві показники ефективності щодо типу даних про гроші. Наприклад, коли службам Analysis Services було встановлено тип валюти (від подвійного), щоб відповідати типу даних грошей SQL Server, було швидко на 13% покращення швидкості обробки (рядки / сек). Для отримання більш швидкої продуктивності в рамках інтеграційних служб SQL Server (SSIS) для завантаження 1,18 ТБ менше ніж за тридцять хвилин, як зазначалося в SSIS 2008 - світовій рекордної продуктивності ETL, було помічено, що змінюються чотири десяткових (9,2) стовпців розміром 5 байт у таблиці TPC-H LINEITEM до грошей (8 байт) покращили швидкість масового введення на 20% ... Причина для підвищення продуктивності - через протокол табличного потоку даних (TDS) SQL Server, який має ключовий принцип проектування для передачі даних у компактному бінарному вигляді та максимально наближеному до внутрішнього формату зберігання SQL Server. Емпірично це спостерігалось під час SSIS 2008 - світовий рекордний тест ефективності ETL з використанням Kernrate; протокол значно знизився, коли тип даних перейшов на гроші з десяткової. Це робить передачу даних максимально ефективною. Складний тип даних потребує додаткових циклів аналізу та процесора для обробки, ніж тип фіксованої ширини.

Тож відповідь на питання "це залежить". Вам потрібно бути обережнішими з певними арифметичними операціями, щоб зберегти точність, але ви можете виявити, що міркування щодо ефективності роблять це вартим.


Як би ви зберігали біткойн тоді?
Панайотис Канавос

@PanagiotisKanavos - я не маю уявлення. Я ніколи не заглядав у біткойни і практично нічого не знаю про це!
Мартін Сміт

6

Я хочу дати інший погляд на MONEY vs. NUMERICAL, багато в чому ґрунтуючись на моїй власній експертизі та досвіді ... Моя точка зору тут - MONEY, тому що я працював з цим протягом значного часу і ніколи насправді не використовував NUMERICAL. .

MONEY Pro:

  • Рідний тип даних . Він використовує нативний тип даних ( ціле число ), такий самий, як і регістр процесора (32 або 64 біт), тому для обчислення не потрібні зайві накладні витрати, тому він менший і швидший ... ГРОШІ потрібно 8 байт і НОМЕРИЧНІ (19, 4 ) потрібно 9 байт (на 12,5% більше) ...

    ГРОШІ швидше до тих пір, поки його використовували для того, щоб це було (як гроші). Як швидко? Мій простий SUMтест на 1 мільйон даних показує, що ГРОШІ 275 мс і ЧИСЛО 517 мс ... Це майже вдвічі швидше ... Чому тест СУМ? Наступне Pro пункт

  • Найкраще за гроші . Гроші найкраще зберігати гроші та робити операції, наприклад, у бухгалтерському обліку. Один звіт може виконати мільйони доповнень (SUM) та кілька множень після завершення операції SUM. Для дуже великих облікових записів це майже вдвічі швидше , і це надзвичайно важливо ...
  • Мала точність грошей . Гроші в реальному житті не повинні бути дуже точними. Я маю на увазі, багато людей можуть піклуватися про 1 цент USD, але як приблизно 0,01 цент USD? Насправді в моїй країні банки більше не переймаються центами (цифра після десяткової коми); Я не знаю про американський банк чи іншу країну ...

MONEY Con:

  • Обмежена точність . MONEY має лише чотири цифри (після коми) точність, тому її потрібно перетворити перед тим, як робити такі операції, як поділ ... Але потім знову moneyне потрібно бути настільки точним, і він повинен використовуватись як гроші, а не просто число ...

Але ... Велике, але тут навіть ваша програма стосується реальних грошей, але не використовуйте їх у багатьох сумарних операціях, як у бухгалтерському обліку. Якщо ви замість цього використовуєте безліч поділів і множин, тоді не слід використовувати ГРОШІ ...


1
Якщо ви збираєтеся сказати, що гроші швидше десяткових, вам потрібно повідомити нам такі речі, як, що rdbms, на якому апаратному забезпеченні, на якій ОС, з якими конкретними даними, на якому конкретному запиті ви говорите. Крім того, якщо він не є цілком точним, я НЕ здійснюю жодних фінансових операцій з цим, оскільки податкова людина буде досить незадоволена тим, що отримує погані номери. Ви дбаєте про тисячний відсоток, якщо, наприклад, маєте справу з американською валютою. Якщо гроші не роблять цього, вони не можуть бути використані.
Хаакон Лотвейт

3
@ HaakonLøtveit цілий потік запитань стосується типу даних SQL Server "гроші", тому я не думаю, що їм потрібно вказувати це у відповіді. Гроші можна використовувати швидше, ніж десяткові за певних обставин (наприклад, завантаження даних), детальну інформацію див. У відповіді Мартіна Сміта. Я погоджуюсь з більшістю цієї відповіді, оскільки є певні випадки використання, які можуть зробити Гроші більш ефективним вибором, ніж десятковий, однак, якщо не існує дуже вагомого випадку його використання, я думаю, цього слід уникати.
Натан Гріффітс

1
Біткойн має 8 десятків. Ви навіть не можете зберігати його у moneyстовпці
Панайотис Канавос

4

Усі попередні повідомлення приносять вагомі бали, але деякі не відповідають точно на це питання.

Питання: Чому хтось віддасть перевагу грошам, коли ми вже знаємо, що це менш точний тип даних і може спричинити помилки при використанні в складних розрахунках?

Ви використовуєте гроші, коли не будете робити складні розрахунки і можете торгувати цією точністю для інших потреб.

Наприклад, коли вам не доведеться робити ці розрахунки, і вам потрібно імпортувати дані з дійсних текстових рядків валюти. Це автоматичне перетворення працює лише з типом даних MONEY:

SELECT CONVERT(MONEY, '$1,000.68')

Я знаю, що ви можете зробити свій режим імпорту. Але іноді не хочеться відтворювати процедуру імпорту за допомогою локальних локальних форматів.

Інший приклад, коли вам не доведеться робити ці обчислення (потрібно просто зберегти значення) і потрібно зберегти 1 байт (гроші займають 8 байт, а десяткові (19,4) займають 9 байт). У деяких додатках (швидкий процесор, велика оперативна пам’ять, повільний IO), як-от просто читання величезної кількості даних, це може бути і швидше.


2

Ви не повинні використовувати гроші, коли потрібно робити множення / ділення на значення. Гроші зберігаються таким же чином, як ціле число, а десяткові - як десятковий і десяткові цифри. Це означає, що гроші в більшості випадків знижуватимуть точність, тоді як десяткові будуть робити це лише тоді, коли вони перетворяться на початкову шкалу. Гроші є фіксованою точкою, тому її масштаб не змінюється під час розрахунків. Однак, оскільки вона є фіксованою точкою, коли вона друкується у вигляді десяткового рядка (на відміну від фіксованої позиції в базовій 2 рядку), значення до шкали 4 представлені точно. Тож за додавання і віднімання гроші чудово.

Десяткова частина представлена ​​в базі 10 внутрішньо, і, таким чином, позиція десяткової крапки також базується на номері основи 10. Що змушує його дробову частину точно представляти його цінність, як і гроші. Різниця полягає в тому, що проміжні значення десятків можуть підтримувати точність до 38 цифр.

З номером з плаваючою комою значення зберігається у двійковій формі, як ніби це ціле число, а позиція десяткової (або двійкової, ах) точки відносно бітів, що представляють число. Оскільки це двійкова десяткова крапка, базові 10 числа втрачають точність відразу після десяткової крапки. 1/5 або 0,2 не можуть бути представлені саме таким чином. Ні гроші, ні десятковий не страждають від цього обмеження.

Досить просто перетворити гроші в десяткові, виконати обчислення, а потім зберегти отримане значення назад у грошове поле або змінну.

Я хочу, щоб речі, які трапляються з числами, просто траплялися, не задумуючись надто багато. Якщо всі обчислення будуть перетворені на десяткові, то мені просто хочеться використовувати десятковий. Я б заощадив грошове поле для відображення.

Я не бачу різниці, щоб змінити свою думку. Гроші займають 4 - 8 байт, тоді як десяткові можуть бути 5, 9, 13 та 17. 9 байт може охопити весь діапазон, який можуть 8 байт грошей. Індексний (порівняння та пошук повинні бути порівнянні).


Дякую за нагороду. Я дивлюся на це, і, хоча отримую те, що намагався сказати, я також бачу, що це дуже заплутано. Можливо, я перепишу його пізніше з деякими прикладами біт проти десяткових.
Джерард ONeill

2

Я знайшов причину використання десяткової над грошима в предметі точності.

DECLARE @dOne   DECIMAL(19,4),
        @dThree DECIMAL(19,4),
        @mOne   MONEY,
        @mThree MONEY,
        @fOne   FLOAT,
        @fThree FLOAT

 SELECT @dOne   = 1,
        @dThree = 3,    
        @mOne   = 1,
        @mThree = 3,    
        @fOne   = 1,
        @fThree = 3

 SELECT (@dOne/@dThree)*@dThree AS DecimalResult,
        (@mOne/@mThree)*@mThree AS MoneyResult,
        (@fOne/@fThree)*@fThree AS FloatResult

Десятичний результат> 1.000000

MoneyResult> 0,9999

FloatResult> 1

Просто протестуйте його і прийміть своє рішення.


2
Ми дуже хотіли б почути (прочитати, тобто) ваш висновок.
Пітер Мортенсен

@PeterMortensen Я думаю, що якщо я хочу мати повноту та точність між типами Money і Decimal, моє рішення має бути десятковою.
QMaster

1
Подумайте про оновлення своєї відповіді фактичним результатом вищезазначеного. Тоді ваш висновок стане очевидним для кожного, хто читає :-)
Агрекс

1
@Ageax Результат доданий до відповіді.
QMaster

1

Я щойно бачив цю запис у блозі: Гроші проти десятків у SQL Server .

Що в основному говорить про те, що гроші мають питання точності ...

declare @m money
declare @d decimal(9,2)

set @m = 19.34
set @d = 19.34

select (@m/1000)*1000
select (@d/1000)*1000

Для money типу ви отримаєте 19.30 замість 19.34. Я не впевнений, чи існує сценарій програми, який ділить гроші на 1000 частин для розрахунку, але цей приклад дійсно містить деякі обмеження.


15
Це не "питання", це "за специфікаціями": «Тип moneyі smallmoneyдані точно відповідають десятитисячній грошовій одиниці, яку вони представляють». як сказано в msdn.microsoft.com/en-us/library/ms179882.aspx, тому кожен, хто говорить "це сміття", не знає, про що він говорить.
Альбірео
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.