问题描述
有一个 sqlite3 我想查询和求和不同的值。我正在尝试做的查询是:
SUM(CAST(amountA AS BIGINT)) as totalA,SUM(CAST(amountB AS BIGINT)) as totalB
当查询找到多个结果时会触发:
error="integer overflow"
查看 sqlite 的文档,似乎没有这样的 BIGINT,但由于相关性,BIGINT 被视为 INTEGER。
是否可以使用 sqlite3 对 BIGINT 数字求和?
编辑
amountA
和 amountB
的数据类型是 TEXT。将其更改为 INTEGER 将在执行以下操作时触发相同的错误:
SUM(amountA) as totalA,SUM(amountB) as totalB
这是因为我存储的值是 1000000000000000000
并且当存储 10 个这样的值时,在对它们求和时它会溢出,因为它溢出了一个 8 字节的有符号整数
解决方法
您应该将整数值存储为 INTEGER
而不是 TEXT
,但对于您的问题,它没有任何区别。
当使用像 SUM()
这样的聚合函数时,任何看起来是整数的字符串值都会被隐式转换为整数,如果所有求和值都是整数,那么结果数据类型也是 INTEGER
。
您的数据总和似乎超过了 SQLite 支持的最大 64 位整数值,即 9223372036854775807
,您得到 integer overflow
。
您可以通过将每个值转换为 REAL
来将数字相加为实数:
SUM(CAST(amountA AS REAL)) as totalA,SUM(CAST(amountB AS REAL)) as totalB
或者使用 SQLite 的 TOTAL()
聚合函数将数字相加为 REAL
并且从不引发整数溢出:
TOTAL(amountA) as totalA,TOTAL(amountB) as totalB
您可以在此处阅读有关 SUM()
和 TOTAL()
的更多信息:Built-in Aggregate Functions
如果您的总和适合 64 位有符号整数 [-9223372036854775808 .. 9223372036854775807] 应该没问题。 您无需将 int 转换为 bigint。
快速演示
with cte(a) as (
select 9223372036854775807 - 100 union all
-- uncommenting next line will cause integer overflow
--select 1 union all
select 100
)
select sum(a),typeof(sum(a)) t
from cte
结果
sum(a) | t |
---|---|
9223372036854775807 | 整数 |
请提及您的 amountA 和 amountB 列的数据类型。是整数吗?我怀疑不是。
不需要强制转换到 bigint。
SUM(amountA ) as totalA,SUM(amountB) as totalB Should be ok.
但首先请分享 amountA 和 amoutB 列的示例数据。恐怕问题不在于 sum() 而是该表中列的数据类型。