人は、名前と複数の属性を持つメタテーブル行としてデータベースに表されます。これらの属性は、キーと値のペアとしてデータテーブルに格納されます(キーと値は別々の列にあります)。 簡略化されたデータモデル
これで、すべてのユーザー(name)とそのすべての属性(data)を取得するクエリがあります。属性は、JSONオブジェクトとして別の列に返されます。次に例を示します。
name data
Florian { "age":25 }
Markus { "age":25, "color":"blue" }
Thomas {}
SQLコマンドは次のようになります。
SELECT
name,
json_object_agg(d.key, d.value) AS data,
FROM meta AS m
JOIN (
JOIN d.fk_id, d.key, d.value AS value FROM data AS d
) AS d
ON d.fk_id = m.id
GROUP BY m.name;
今私が直面している問題は、Key-valueテーブルに属性が格納されていないThomasのようなユーザーが、select関数で表示されないことです。これは、JOIN
のみを実行し、LEFT OUTER JOIN
は実行しないためです。
LEFT OUTER JOIN
を使用すると問題が発生し、json_object_agg
がNULL
の値を集計しようとしてエラーで終了します。
したがって、ユーザーのkey-columnがNULL
であるかどうかを確認し、空の配列を返して、json_object_agg
が空の[〜# 〜] json [〜#〜]オブジェクト。
しかし、SQLで空の配列を作成する関数は実際にはありません。私が見つけた最も近いものはこれでした:
select '{}'::text[];
COALESCE
と組み合わせると、クエリは次のようになります。
json_object_agg(COALESCE(d.key, '{}'::text[]), COALESCE(d.value, '{}'::text[])) AS data
しかし、これを使用しようとすると、次のエラーが発生します。
ERROR: COALESCE types text and text[] cannot be matched
LINE 10: json_object_agg(COALESCE(d.key, '{}'::text[]), COALES...
^
Query failed
PostgreSQL said: COALESCE types text and text[] cannot be matched
したがって、実行時のd.key
は単一の値であり、配列ではないようです。
だから私はjson_object_agg
を取り、それをjson_object
で置き換えようとしましたaggregate私にとってキーではありません:
json_object(COALESCE(array_agg(d.key), '{}'::text[]), COALESCE(array_agg(d.value), '{}'::text[])) AS data
しかし、そこにnull value not allowed for object key
というエラーが表示されます。したがって、COALESCE
は配列が空であることを確認しません。
それで、結合された列が空であるかどうかをチェックする関数があり、もしそうであれば単純なJSONオブジェクトだけを返しますか?
または、私の問題を解決する他の解決策はありますか?
_left join
_をcoalesce()
とともに使用します。デフォルト値として_'{}'::json
_を使用します。
_select name, coalesce(d.data, '{}'::json) as data
from meta m
left join (
select fk_id, json_object_agg(d.key, d.value) as data
from data d
group by 1
) d
on m.id = d.fk_id;
name | data
---------+------------------------------------
Florian | { "age" : "25" }
Marcus | { "age" : "25", "color" : "blue" }
Thomas | {}
(3 rows)
_