web-dev-qa-db-ja.com

PostgreSQL 9.4のjsonb型をfloatに変換する方法

私は次のクエリを試しています:

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

(+1.0は、変換を強制的に浮動にするためのものです。実際のクエリははるかに複雑です。このクエリは、問題の単なるテストケースです。)

エラーが表示されます:

ERROR:  operator does not exist: jsonb + numeric

明示的なキャストを追加する場合:

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

エラーは次のようになります。

ERROR:  operator does not exist: jsonb + double precesion

ほとんどのjsonb値をfloatにキャストできないことを理解していますが、この場合、latsはすべてJSON番号であることを知っています。

Jsonb値をfloatにキャストする(またはキャスト不可の場合はNULLを返す)関数はありますか?

31
fadedbee

JSONから値を取得するには、2つの操作があります。最初の1つ ->JSONを返します。 2番目の->>はテキストを返します。

詳細: JSON関数と演算子

試して

SELECT (json_data->'position'->>'lat')::float + 1.0 AS lat
FROM updates
LIMIT 5
80

ドキュメントごと 、関数もあります

_jsonb_populate_record()
jsonb_populate_recordset()
_

Json twinsのアナログ(pg 9.3以降に存在)

_json_populate_record()
json_populate_recordset()
_

定義済みの行タイプが必要です。既存のテーブルの行タイプを使用するか、_CREATE TYPE_で定義します。または、一時テーブルを一時的に置き換える:

CREATE TEMP TABLE x(lat float);

単一の列または列の長いリストを指定できます。

namekeyと一致する列のみが入力されますjsonオブジェクト。 valueは列typeに強制され、互換性があるか、例外が発生します。他のキーは無視されます。

_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()を使用して、エントリごとに配列を複数の行に分解します。

これは、jsonを使用したPostgres 9.3でも同じように機能します。 text内の数値データに対して、jsonbから内部へ/から内部的にキャストする必要がないという追加の利点があります。

6

私の知る限り、Postgresにはjson-> floatキャストがないので、明示的な(json_data->'position'->'lat')::text::floatキャスト

5
knitti

これが「JSONB float変換」検索の上位ヒットとして現れるため、明確化を追加します-JSON変換を括弧で囲む必要があることに注意してください、そしてthen「::」キャスティングを適用します。

上記のように、正しい方法は次のとおりです。

(json_data #>> '{field}')::float

代わりにこれを試すと失敗します:

json_data #>> '{field}'::float

これは私が自分のコードで犯した間違いであり、それを見るのに少し時間がかかりました-気がついたら簡単に修正できます。

3
rocksteady

JSON値をテキストにキャストしてからフロートする必要があります。

これを試して:

(json_data #>> '{field}')::float
1
Luis Castillo