Сумма в поле VARCHAR преобразована в DECIMAL без добавления чисел после десятичного числа - PullRequest
0 голосов
/ 28 марта 2019

У меня есть поле VARCHAR, в котором хранится значение типа 0.00000000.

Я хочу выполнить запрос отчета к SUM всем этим VARCHAR полям, что означает, что я должен преобразовать ихна номер, чтобы добавить их.

Вот мой запрос, который не дает ошибок, но возвращает неправильный номер:

SELECT SUM(CAST(IFNULL(tx.received_amount, '0.00000000') AS DECIMAL(16, 16)))
FROM account
JOIN account_invoice
    ON account_invoice.account_id = account.id
JOIN withdrawal
    ON withdrawal.invoice_id = account_invoice.invoice_id
JOIN tx
    ON tx.id = withdrawal.tx_id
    AND tx.currency = 'BTC'
    AND tx.created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)
WHERE account.id = 1

Вот что я получаю: 100 x 1.12345678 = 100.00000000

Вот что я должен получить: 100 x 1.12345678 = 112.34567800

Почему SUM не добавляет цифры после десятичной дроби?

Ответы [ 3 ]

2 голосов
/ 28 марта 2019

Вы не используете тип данных DECIMAL в соответствии с вашим вариантом использования. DECIMAL(16, 16) объявляет десятичное число с 16 цифрами и с 16 десятичными цифрами. Это не может содержать значение больше 1.

Рассмотрим:

SELECT CAST('1.12345678' AS DECIMAL(16, 16)) 

Возвращает: 0.9999999999999999.

Вы, вероятно, хотите что-то вроде DECIMAL(16, 8) вместо этого, так как ваши строки, кажется, имеют 8 десятичных знаков.


С документация MySQL :

Синтаксис объявления для столбца DECIMAL: DECIMAL(M,D). Диапазоны значений для аргументов следующие:

  • M - максимальное количество цифр (точность). Диапазон значений от 1 до 65.

  • D - количество цифр справа от десятичной точки (шкала). Он имеет диапазон от 0 до 30 и не должен превышать M.

1 голос
/ 28 марта 2019

Ответ GMB обычно является лучшим выбором, но если вам действительно нужно вывести (a_really_precise_number) * 100, вы можете сделать это на стороне приложения, фактически передав его в виде строки в язык, который поддерживает произвольно большие числа, а затем приведите егосторона приложения.Если в вашей базе данных есть числа более точные, чем 16 цифр, вы, вероятно, уже используете номер, который поддерживает это в вашем приложении.

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

Третий вариант, если вы просто умножаете его на степень 10, например, N * 100, и выводите результат, передаете его в приложение в виде строки, а затем просто анализируете его, чтобы переместить десятичное число в 2 места, например, так:

function shiftDec(str, shift){
  // split on decimal point
  var decPoint = str.indexOf(".");
  var decInt = str.substr(0, decPoint);
  var decMod = str.substr((decPoint+1));

  // move decimal 'shift' places to simulate N*100.
  if(shift > 0){
    var shiftCopy = decInt .substr(0,shift);
    decInt = decInt + shiftCopy;
    decMod = decMod .substr(shift);
  } else {
    var shiftCopy = decInt .substr((decInt.length + shift));
    decInt = decInt .substr(0,(decInt.length + shift));
    decMod = shiftCopy + decMod;
  }
  return decInt + '.' + decMod;
}
var result = shiftDec("1234567891234567.8912345678912345", 2);
document.write(result);
0 голосов
/ 28 марта 2019

Вы не должны использовать DECIMAL (16,16)

SELECT 100 * CAST('1.123' AS DECIMAL(16,16))

99,999 ...

SELECT 100 * CAST('1.123' AS DECIMAL(16, 10))

112,300 ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...