如何从 SQLite 数据库中选择浮点无穷大文字?

比尔盖*_*尔盖子 3 sql sqlite floating-point infinity

我有一个 SQLite 数据库,其中有一个名为 的表measurements,其中包含一些由功率计测量的实验数据。它们作为数据类型存储REAL在名为 的字段中power_dbm。在某些测量中,读数可能会超出范围,仪表由于超出范围或低于范围而无法获取读数,因此使用+Inf和来表示这些值。-Inf

例如,这是一些数据。

sqlite> SELECT power_dbm, typeof(power_dbm) from measurements;
-10.312|real
-9.908|real
-11.344|real
-Inf|real
Run Code Online (Sandbox Code Playgroud)

如您所见,有一个负无穷大的浮点数。不幸的是,我不知道从数据库中选择这些值的正确语法。我试过:

sqlite> SELECT freq_hz, power_dbm from measurements WHERE power_dbm=-Inf;
Error: no such column: Inf

sqlite> SELECT freq_hz, power_dbm from measurements WHERE power_dbm='-Inf'
(nothing returned)

sqlite> SELECT freq_hz, power_dbm from measurements WHERE power_dbm='-infinity';
(nothing returned)

sqlite> SELECT freq_hz, power_dbm from measurements WHERE power_dbm=-1/0;
(nothing returned)

sqlite> SELECT freq_hz, power_dbm from measurements WHERE power_dbm is -1/0;
(incorrect results returned, power_dbm is null instead of negative infinity)
Run Code Online (Sandbox Code Playgroud)

在 SQL/SQLite 中指定正无穷大或负无穷大的字面值的正确语法是什么?对相关文档的任何其他参考也将不胜感激。

比尔盖*_*尔盖子 7

解决方案 1:使用不可能巨大的浮点文字

我发现编写一个不可能的巨大浮点文字是9e999构造+Inf/的一种方法-Inf

sqlite> SELECT 9e999;
Inf

sqlite> SELECT -9e999;
-Inf

sqlite> SELECT freq_hz, power_dbm, typeof(power_dbm) FROM measurements
   ...> WHERE power_dbm=-9e999;
370000000|-Inf|real
440000000|-Inf|real
510000000|-Inf|real
580000000|-Inf|real
Run Code Online (Sandbox Code Playgroud)

解决方案 2:ieee754()与 Infinity 的硬编码指数/有效数一起使用

您可以通过 function 手动构造 IEEE 754 表示形式中的指数和有效+Inf数。这是我在找到窍门之前使用的原始解决方案......-Infieee754()9e999

sqlite> SELECT ieee754(4503599627370496, 972);
Inf

sqlite> SELECT ieee754(-4503599627370496, 972);
-Inf

sqlite> SELECT freq_hz, power_dbm, typeof(power_dbm) FROM measurements
   ...> WHERE power_dbm=ieee754(-4503599627370496, 972);
370000000|-Inf|real
440000000|-Inf|real
510000000|-Inf|real
580000000|-Inf|real
Run Code Online (Sandbox Code Playgroud)

和其他相关函数的详细用法ieee754()记录在Floating Point Numbers中。

解决方案 3:使用参数化 SQL 查询

使用ieee754(-4503599627370496, 972)感觉像是比像 之类的随机值更严格的构造9e999,但当9e999您想要快速查看数据时,足以在控制台中手动键入命令,因此正确性不是真正的问题。

在实际的程序中,无论如何,我们都会使用参数化的 SQL 查询而不是处理字符串,只需在编程语言中传递本机Infinity常量(例如 Python 的)就足够了。math.inf

$ python3
Python 3.9.9 (main, Nov 19 2021, 00:00:00) 
[GCC 10.3.1 20210422 (Red Hat 10.3.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> import sqlite3
>>> DB_FILE = "./data.db"
>>> con = sqlite3.connect(DB_FILE)
>>> cur = con.cursor()
>>> cur.execute(
...     "SELECT power_dbm from measurements "
...     "WHERE power_dbm=?", (-math.inf,)).fetchall()
[(-inf,), (-inf,), (-inf,), (-inf,)]
Run Code Online (Sandbox Code Playgroud)