私は次のクエリを試しています:
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を返す)関数はありますか?
JSON
から値を取得するには、2つの操作があります。最初の1つ ->
はJSON
を返します。 2番目の->>
はテキストを返します。
詳細: JSON関数と演算子
試して
SELECT (json_data->'position'->>'lat')::float + 1.0 AS lat
FROM updates
LIMIT 5
ドキュメントごと 、関数もあります
_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);
単一の列または列の長いリストを指定できます。
nameがkeyと一致する列のみが入力されます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
から内部へ/から内部的にキャストする必要がないという追加の利点があります。
私の知る限り、Postgresにはjson-> floatキャストがないので、明示的な(json_data->'position'->'lat')::text::float
キャスト
これが「JSONB float変換」検索の上位ヒットとして現れるため、明確化を追加します-JSON変換を括弧で囲む必要があることに注意してください、そしてthen「::」キャスティングを適用します。
上記のように、正しい方法は次のとおりです。
(json_data #>> '{field}')::float
代わりにこれを試すと失敗します:
json_data #>> '{field}'::float
これは私が自分のコードで犯した間違いであり、それを見るのに少し時間がかかりました-気がついたら簡単に修正できます。
JSON値をテキストにキャストしてからフロートする必要があります。
これを試して:
(json_data #>> '{field}')::float