简体   繁体   English

PostgreSQL JSON 查询修改数组

[英]PostgreSQL JSON query modify an array

I have a some json configuration in the table something like below我在表中有一些 json 配置,如下所示

create table X (name varchar, config json);

insert into X (name, config) values (
  'name1',
  '{"method":"XYZ","frequent":["MONTHLY","WEEKLY"]}'  
);

insert into X (name, config) values (
  'name2',
  '{"method":"ABC","frequent":["WEEKLY", "DAILY"]}'  
);

Basically this frequent property in json column can contain any number of elements as this is an array.基本上 json 列中的这个频繁属性可以包含任意数量的元素,因为这是一个数组。

Now I want to modify all the records in a table where "frequent":["MONTHLY", "WEEKLY"] to "frequency":["P1M","P1W"] and so on..现在我想修改一个表中的所有记录,其中 "frequent":["MONTHLY", "WEEKLY"] 为 "frequency":["P1M","P1W"] 等等..

So output should be something like that所以 output 应该是这样的

'name1','{"method":"XYZ","frequency":["P1M","P1W"]}'
'name2','{"method":"ABC","frequency":["P1W","P1D"]}'  

Should I go with CASE WHEN and THEN approach or is there any better way to do that?我应该使用 CASE WHEN 和 THEN 方法的 go 还是有更好的方法来做到这一点?

version: 9.5+版本:9.5+

If you have to use more complex rules than just taking the first character of the original frequency word (eg 1 if it's less than a month, 3 if it's a quarter), you have to use CASE WHEN... .如果您必须使用更复杂的规则,而不仅仅是获取原始频率词的第一个字符(例如,如果小于一个月,则为 1,如果是四分之一,则为 3),您必须使用CASE WHEN... The whole update query will look like this:整个更新查询将如下所示:

WITH modified_frequencies AS (
    SELECT 
        name,
        config::jsonb->'method'::text AS method,
        CASE
            WHEN frequency_word = 'MONTHLY' THEN 'P1M'
            WHEN frequency_word = 'WEEKLY' THEN 'P1W'
            WHEN frequency_word = 'DAILY' THEN 'P1D'
            WHEN frequency_word = 'QUARTERLY' THEN 'P3M'
        END AS modified_frequency_word
    FROM test.X, 
         json_array_elements_text((config::jsonb->'frequent')::json) AS frequency_word
),
    modified_configs AS (
        SELECT
            name,
            json_build_object(
                'method', method,
                'frequent', array_agg(modified_frequency_word)
            ) AS modified_config
        FROM modified_frequencies
        GROUP BY name, method
)
UPDATE test.X x
SET config = modified_config
FROM modified_configs
WHERE x.name = modified_configs.name

Basically, you have to first unnest the JSON array, so that you can work on the individual elements in it, then put back the whole JSON structure together, which then you can use in the update statement.基本上,您必须首先取消嵌套 JSON 数组,以便您可以处理其中的各个元素,然后将整个 JSON 结构放回一起,然后您可以在更新语句中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM