编辑: 答案在这里:Is floating point math broken?有助于理解这个问题。但是,这个问题与语言无关。它特定于由SQLite处理的浮点数的记录行为和亲和性。对不同的问题有一个非常相似的答案!=重复的问题。
问题: 我有一个相当复杂的SQLite Where子句比较数值。我已阅读并且"思考"我在这里了解数据类型文档:https://www.sqlite.org/datatype3.html
仍然对SQLite用于确定比较子句中的数据类型的逻辑感到困惑,例如=,>,<,<>我可以将我的例子缩小到这一点测试SQL,结果对我来说没什么意义。
reconnectFailed
select语句(TestComparison2)中的第二个表达式是将等式的左侧转换为TEXT值。我可以通过将等式的右侧转换为TEXT并且结果= 1来证明这一点。
显然,我错过了SQLite计算Affinity的方式。这些值来自大型/复杂查询中的列。我应该将WHERE / Join子句中的等式的两边都投射到TEXT以避免这些问题吗?
答案 0 :(得分:1)
您未获得预期结果的原因是基础结果将是浮点数。
虽然DataTypes in SQLite3涵盖的很多,但您还应该考虑 Expressions 中的以下部分: -
类型名转换处理的亲和力
NONE
将值转换为没有亲和力的类型名称会导致该值转换为BLOB。投射到BLOB包括第一个 在数据库连接的编码中将值转换为TEXT, 然后将得到的字节序列解释为BLOB而不是 TEXT。
TEXT
要将BLOB值转换为TEXT,组成BLOB的字节序列将被解释为使用数据库编码的文本 编码
将一个INTEGER或REAL值转换为TEXT会将该值渲染为via sqlite3_snprintf()除了生成的TEXT使用的编码 数据库连接。
REAL
将BLOB值转换为REAL时,该值首先转换为TEXT。
将TEXT值转换为REAL时,最长可能的前缀 可以解释为实数的值是从中提取的 TEXT值和余数被忽略。 TEXT中的任何前导空格 从TEXT收敛到REAL时忽略值。
如果没有可以解释为实数的前缀,则 转换结果为0.0。
INTEGER
将BLOB值转换为INTEGER时,该值首先转换为TEXT。 将TEXT值转换为INTEGER时,可以解释为可以解释为整数的值> gt的最长前缀 从TEXT值和余数忽略。任何领先的空间 从TEXT转换为INTEGER时的TEXT值将被忽略。
如果没有可以解释为整数的前缀, 转换结果为0.
如果前缀整数大于+9223372036854775807那么 演员阵容的结果正好是+9223372036854775807。 同样,如果 前缀整数小于-9223372036854775808然后得到的结果 演员阵容正好是-9223372036854775808。
当转换为INTEGER时,如果文本看起来像带有指数的浮点值,则指数将被忽略,因为它不是 整数前缀的一部分。例如,“(CAST'123e + 5'AS INTEGER)” 结果是123,而不是12300000。
CAST运算符仅理解十进制整数 - 十六进制整数的转换停止在“0x”前缀的“x”处 十六进制整数字符串,因此CAST的结果始终为零。
将REAL值转换为INTEGER会导致REAL值与零之间的整数最接近REAL值。如果 REAL大于最大可能的有符号整数 (+9223372036854775807)然后结果是最大可能的签名 整数,如果REAL小于最小可能的有符号整数 (-9223372036854775808)然后结果是最不可能的签名 整数。
在SQLite版本3.8.2(2013-12-06)之前,将大于+9223372036854775807.0的REAL值转换为整数会导致 最负的整数,-9223372036854775808。这种行为意味着 在执行等效操作时模拟x86 / x64硬件的行为 铸造。
NUMERIC
首先将TEXT或BLOB值转换为NUMERIC强制转换为REAL,然后将结果进一步转换为 INTEGER当且仅当从REAL转换为INTEGER无损时 并且可逆。 这是SQLite中唯一的NUMERIC上下文 和INTEGER的亲密关系表现不同。
将REAL或INTEGER值转换为NUMERIC是一种无操作,即使是真实的 value可以无损地转换为整数。
在此部分之前有一个关于文字值的部分(即,可能只需要将投射应用于从列中提取的值)。
尝试: -
SELECT
round(CAST(10 AS NUMERIC) + CAST(254.53 AS NUMERIC),2) = round(CAST(264.53 AS NUMERIC),2) AS TestComparison1,
round(CAST(10 AS NUMERIC) + CAST(254.54 AS NUMERIC),2) = round(CAST(264.54 AS NUMERIC),2) AS TestComparison2