У меня есть Sqlitedb со столбцом: amount text not null
В столбце суммы хранятся значения доллара в этом формате: $1.01, $40.58 и т.д.
Я пытаюсь суммировать значения доллара, используя
SELECT SUM(amount) FROM record WHERE date LIKE '"+date+"'"
Однако это не работает, по-видимому, потому, что вы не можете добавить текст. Я знаю, что это не идеальное хранилище, но как бы я начал разбирать суммы, чтобы я мог их добавить?
Ну, как вы сказали, это далеко не идеальный способ хранения значений (которые должны быть в формате decimal
/real
с самого начала), однако вы можете сделать что-то вроде этого:
SELECT SUM(SUBSTR(amount, 2)) FROM record WHERE date LIKE '"+date+"'"
Метод SUBSTR
представляет собой текстовую функцию, которая будет принимать часть текста (в данном случае, от начального индекса). Проблема здесь заключалась в знаке $
, который был смущен преобразованием динамического типа, полагая, что вы пытались добавить строки вместе.
Теперь это должно работать, поскольку SQLLite позволяет динамическую типизацию (что в двух словах означает, что значение используется для сравнения, а не контейнер).
Намного лучше хранить суммы в виде незамасшенных целых чисел и просто форматировать их, когда это необходимо для отображения. Вы получаете более компактное хранилище, а также более быстрое и быстрое добавление. Использование целых чисел позволяет избежать риска ошибок округления в представлениях с плавающей запятой.
Безмасштабированным я имею в виду, что $1.23 будет храниться как целое число 123. (Используйте long
в вашем Java-коде и INTEGER
в SQL.)
Вы можете форматировать суммы для отображения, запрашивая локаль для соответствующей информации:
// implement this any way you like!
long amount = getAmountFromDb();
// use default locale if you want
Locale locale = getLocaleFromSomewhere();
Currency currency = Currency.getInstance(locale);
NumberFormat format = NumberFormat.getCurrencyInstance(locale);
int scale = currency.getDefaultFractionDigits();
BigDecimal scaledAmount = new BigDecimal(unscaledBalance).movePointLeft(scale);
String textAmount = format.format(scaledAmount);