温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - PostgreSQL compare two jsonb objects
postgresql jsonb postgresql-9.5

其他 - PostgreSQL比较两个jsonb对象

发布于 2020-03-27 11:57:44

使用PostgreSQL(v9.5)时JSONB格式提供了绝佳的机会。但是现在,我只能执行一个相对简单的操作了;

比较两个jsonb对象;查看一个文档与另一个文档相比有何不同或缺失。

到目前为止我有什么

WITH reports(id,DATA) AS (
          VALUES (1,'{"a":"aaa", "b":"bbb", "c":"ccc"}'::jsonb),
                 (2,'{"a":"aaa", "b":"jjj", "d":"ddd"}'::jsonb) )
SELECT jsonb_object_agg(anon_1.key, anon_1.value)
FROM
  (SELECT anon_2.key AS KEY,
      reports.data -> anon_2.KEY AS value
   FROM reports,
     (SELECT DISTINCT jsonb_object_keys(reports.data) AS KEY
      FROM reports) AS anon_2
   ORDER BY reports.id DESC) AS anon_1

应该返回第1行与第2行相比的差:

'{"b":"bbb", "c":"ccc", "d":null}'

相反,它还会返回重复项({"a": "aaa"})。也; 一般而言,可能会有更优雅的方法!

查看更多

查看更多

提问者
Joost Döbken
被浏览
125
Dmitry Savinkov 2016-03-18 05:23

更新

CREATE OR REPLACE FUNCTION jsonb_diff_val(val1 JSONB,val2 JSONB)
RETURNS JSONB AS $$
DECLARE
  result JSONB;
  v RECORD;
BEGIN
   result = val1;
   FOR v IN SELECT * FROM jsonb_each(val2) LOOP
     IF result @> jsonb_build_object(v.key,v.value)
        THEN result = result - v.key;
     ELSIF result ? v.key THEN CONTINUE;
     ELSE
        result = result || jsonb_build_object(v.key,'null');
     END IF;
   END LOOP;
   RETURN result;
END;
$$ LANGUAGE plpgsql;

查询:

SELECT jsonb_diff_val(
    '{"a":"aaa", "b":"bbb", "c":"ccc"}'::jsonb,
    '{"a":"aaa", "b":"jjj", "d":"ddd"}'::jsonb
);
            jsonb_diff_val             
---------------------------------------
 {"b": "bbb", "c": "ccc", "d": "null"}
(1 row)