使用 BIGINT 时 Sqlite 整数溢出

问题描述

一个 sqlite3 我想查询和求和不同的值。我正在尝试做的查询是:

SUM(CAST(amountA AS BIGINT)) as totalA,SUM(CAST(amountB AS BIGINT)) as totalB

查询找到多个结果时会触发:

error="integer overflow"

查看 sqlite 的文档,似乎没有这样的 BIGINT,但由于相关性,BIGINT 被视为 INTEGER。

是否可以使用 sqlite3 对 BIGINT 数字求和?

编辑

amountAamountB 的数据类型是 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

,

But as soon as INTEGER values are read off of disk and into memory for processing,they are converted to the most general datatype (8-byte signed integer)

如果您的总和适合 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() 而是该表中列的数据类型。