关于sql:如何将PostgreSQL 9.4的jsonb类型转换为float

How to convert PostgreSQL 9.4's jsonb type to float

我正在尝试以下查询:

1
SELECT (json_data->'position'->'lat') + 1.0 AS lat FROM updates LIMIT 5;

(+ 1.0只是强制转换为浮点数。我的实际查询要复杂得多,这个查询只是问题的一个测试用例。)

我收到错误:

1
ERROR:  operator does NOT exist: jsonb + NUMERIC

如果我添加显式转换:

1
SELECT (json_data->'position'->'lat')::FLOAT + 1.0 AS lat FROM updates LIMIT 5;

错误变成:

1
ERROR:  operator does NOT exist: jsonb + DOUBLE precesion

我知道大多数jsonb值都不能转换成浮点数,但在这种情况下我知道lats都是JSON数。

是否有一个函数将jsonb值转换为浮点数(或为uncastable返回NULL)?


JSON获取值有两种操作。第一个->将返回JSON。第二个->>将返回文本。

详细信息:JSON函数和运算符

尝试

1
2
3
SELECT (json_data->'position'->>'lat')::FLOAT + 1.0 AS lat
FROM updates
LIMIT 5


根据文档,还有功能

1
2
jsonb_populate_record()
jsonb_populate_recordset()

与他们的json双胞胎类比(自第9.3页开始)

1
2
json_populate_record()
json_populate_recordset()

您需要预定义的行类型。使用现有表的行类型或使用CREATE TYPE定义一个。或者用临时表替换:

1
CREATE TEMP TABLE x(lat FLOAT);

可以是单列或长列列。

仅填充那些列,其中名称与JSON对象中的键匹配。该值被强制转换为列类型,并且必须兼容或引发异常。其他键被忽略。

1
2
3
4
SELECT lat + 1  -- no need for 1.0, this is float already
FROM   updates u
     , jsonb_populate_record(NULL::x, u.json_data->'position')
LIMIT  5;

在这里使用隐式LATERAL JOIN

同样,使用jsonb_populate_recordset()将数组分解为每个条目多行。

这与Postgres 9.3中使用JSON的方式相同。还有一个额外的好处是,jsonb中的数字数据不需要内部转换到text


AFAIK在Postgres中没有json-> float Cast,所以你可以尝试一个明确的(json_data->'position'->'lat')::text::float强制转换


添加澄清,因为这是"JSONB浮点转换"搜索的最高点 - 请注意,您需要将JSON转换包装在括号中,然后应用'::'转换。

如上所述,正确的方法是:

1
(json_data #>> '{field}')::FLOAT

如果您尝试这样做,它将失败:

1
json_data #>> '{field}'::FLOAT

这是我在我的代码中犯的错误,我花了一段时间才看到它 - 一旦我注意到它就很容易修复。


您必须将json值转换为text,然后再浮动。

试试这个:

1
(json_data #>> '{field}')::FLOAT