Problema al guardar valores decimales (cifras monetarias ) en una base de datos mysql

En el momento estoy guardando varios valores que representan cifras monetarias, estos valores los extraigo de un archivo csv y insertados en una base de datos . Algunos de estos valores se encuentran de la siguiente manera:

// pueden llegar con el punto de mil
// siete mil treinta y cuatro 
7.034 
// o sin punto de mil pero con valores decimales
// cuatro mil treinta y cuatro con treinta y cuatro décimas
4034.34

El problema ocurre cuando cuando realizo la suma de estos, dejando el punto en cualquiera de los casos el sistema tiende a redondear las cifras lo cual hace que el total sea muy impreciso, tratando de resolver esto antes de hacer la inserción elimino los puntos.

El campo en el que guardo los datos es 'DECIMAL(10,2)' aunque lo he intentado con NUMERIC o FLOAT pero se sigue presentando lo mismo.

//
7034 
// 
403434

En el caso del primer valor, al sumarlo da un resultado mas exacto al no tener decimales, lo que no ocurre con el segundo valor que si posee decimales, pues interpreta los últimos dos dígitos como si fuese parte de este es decir " cuatrocientos tres mil, cuatrocientos treinta y cuatro.

espero hacerme entender

1
задан 29.12.2016, 16:29
0 ответов

Так как ты используешь php porqué не относиться к данным? В данных, которые мстят тебе CSV где точке . будьте использованы для единиц тысячи используй функцию str_replace (), так что у тебя есть связность во всех данных и смоги относиться к ним систематически, так как а будет невозможно, потому что mysql никогда он не будет знать, - единица ли тысячи эта точка или десятичный.

Сначала с десятичной функцией (n, 0) в sql ты возвращаешь числа без десятичных, тогда ты будешь знать, что эта точка - для единиц тысячи.

// pueden llegar con el punto de mil
// siete mil treinta y cuatro 
7.034 
$csv1 = str_replace('.','','7.034');
(float) $csv1;
// o sin punto de mil pero con valores decimales
// cuatro mil treinta y cuatro con treinta y cuatro décimas
4034.34
2
ответ дан 03.12.2019, 17:56

Мне приходят в голову выборы, чтобы уважать десятичного, если тебе нужно, чтобы были точными операции или, а, округлять.

Уважать десятичных:

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

// Antes de sumar
settype($cifra_monetaria, 'double');
var_dump($cifra_monetaria); // Te dirá el tipo de variable

Округлять десятичные

Используй round:

echo round(3.6, 0);      // 4
echo round(1.95583, 2);  // 1.96
1
ответ дан 03.12.2019, 17:56

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

Тем не менее, если десятичных никогда нет 3, мы можем думать немного "грязное" решение:
удалять все точки, которые после 1 цифры и продолженные 3 цифрами (ни больше ни меньше).

function eliminar_puntos_tres_digitos($valor){
    return preg_replace('/(\d)\.(?=\d{3}(?!\d))/', '$1', $valor);
}

Нужно отмечать, что этот метод не удался бы с любым числом, у которого было бы 3 десятичных числа.

Результат:

Original: 123.00        Resultado: 123.00
Original: 123.0001      Resultado: 123.0001
Original: 123.456       Resultado: 123456
Original: 123.456.789   Resultado: 123456789
Original: 123.          Resultado: 123.
Original: .123          Resultado: .123
Original: 123.456.7     Resultado: 123456.7
Original: 123.456.789.1 Resultado: 123456789.1

Demo: http://ideone.com/f3lsrb

1
ответ дан 03.12.2019, 17:56