如何从 SQLite 数据库中 select 浮点无限文字?
How do I select floating-point infinity literals from a SQLite database?
我有一个名为table的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
如你所见,有一个负无穷大的浮点数。不幸的是,我不知道从数据库中 select 这些值的正确语法。我试过了:
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)
在 SQL/SQLite 中指定正无穷大或负无穷大的字面值的正确语法是什么?对相关文档的任何其他参考也将不胜感激。
解决方案 1:使用 impossibly-huge floating-point 文字
我发现写一个 impossibly-huge floating-point 文字如 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
解决方案 2:将 ieee754()
与硬编码 exponent/significand 一起用于 Infinity
您可以通过函数 ieee754()
从 IEEE 754 表示中的指数和尾数手动构造 +Inf
和 -Inf
。这是我在找到 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
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,)]
选角适合我:
SELECT power_dbm from measurements WHERE CAST(power_dbm AS CHARACTER) ='Inf';
我有一个名为table的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
如你所见,有一个负无穷大的浮点数。不幸的是,我不知道从数据库中 select 这些值的正确语法。我试过了:
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)
在 SQL/SQLite 中指定正无穷大或负无穷大的字面值的正确语法是什么?对相关文档的任何其他参考也将不胜感激。
解决方案 1:使用 impossibly-huge floating-point 文字
我发现写一个 impossibly-huge floating-point 文字如 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
解决方案 2:将 ieee754()
与硬编码 exponent/significand 一起用于 Infinity
您可以通过函数 ieee754()
从 IEEE 754 表示中的指数和尾数手动构造 +Inf
和 -Inf
。这是我在找到 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
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,)]
选角适合我:
SELECT power_dbm from measurements WHERE CAST(power_dbm AS CHARACTER) ='Inf';