あなたは常にキーの最新の値を持つようにしたい場合は、あなたがCTE
とRANK()
ウィンドウ関数を使用できます。
SELECT * FROM p;
┌────┬───────────┬──────────────────────┬────────┬────────────────────────────┐
│ id │ key │ value │ userid │ modification_time │
├────┼───────────┼──────────────────────┼────────┼────────────────────────────┤
│ 1 │ email │ [email protected] │ 1 │ 2016-10-05 12:53:32.936704 │
│ 2 │ firstName │ thomas │ 1 │ 2016-10-05 12:53:32.936704 │
│ 3 │ lastName │ reggi │ 1 │ 2016-10-05 12:53:32.936704 │
│ 4 │ email │ [email protected] │ 1 │ 2016-11-06 15:53:48.025775 │
└────┴───────────┴──────────────────────┴────────┴────────────────────────────┘
(4 rows)
WITH info_with_rank_for_user AS (
SELECT userId,
modification_time,
value,
key,
RANK() OVER (PARTITION BY userId, key ORDER BY id DESC)
FROM p
)
SELECT userId,
json_object_agg(key, value),
MAX(modification_time) AS last_settings_modification_time
FROM info_with_rank_for_user
WHERE rank = 1
GROUP BY userId
;
┌────────┬────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────┐
│ userid │ json_object_agg │ last_settings_modification_time │
├────────┼────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────┤
│ 1 │ { "email" : "[email protected]", "firstName" : "thomas", "lastName" : "reggi" } │ 2016-11-06 15:53:48.025775 │
└────────┴────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────┘
(1 row)
がそれを制御することができ、保管にキーを: 'jsonb_object_agg'(他の集約関数と同様)は、' ORDER BY'節、f.exを受け取ります。 'key'を最高の' id'で保持するために 'jsonb_object_agg(key、value ORDER BY id)'を使用します(最後に追加されたキーと値のペアは維持されます) – pozs
はい、しかし、それは文書化されていない実装の詳細'jsonb'では、最後に追加されたペアが保持されることになります。たぶん私はあまりにも心配です。問題に対処するための答えにいくつかのアイデアを追加します。 –
これは文書化されています(https://www.postgresql.org/docs/current/static/datatype-json.html):*入力に重複キーが指定されている場合、最後の値だけが保持されます。* - 'json'型でも同様の扱いがあります:*値のJSONオブジェクトに同じキーが複数回含まれている場合、すべてのキーと値のペアが保持されます。 (処理機能は最後の値を有効なものと見なします。)* – pozs