JSONB column: sort only content of arrays stored in column with mixed JSONB content

我的梦境 提交于 2019-12-24 14:35:55

问题


I have a table with JSONB column storing JSONB arrays/strings (value_r column in the below example). What would be the simplest (and efficent) way to sort only content of JSONB arrays within JSONB column (storing also strings)?

I've been looking for the simplest method (as query, or procedure is needed?) because I have to apply this in more complicated SQL code.

Here is the test code:

CREATE TABLE test_table (
    id integer,
    ordinality bigint,
    key_r text,
    value_r jsonb
);

INSERT INTO test_table VALUES (1, 1, 'carType', '"sedan"');
INSERT INTO test_table VALUES (1, 1, 'equipment', '["AT", "AC"]');
INSERT INTO test_table VALUES (1, 2, 'extra', '["GPS"]');
INSERT INTO test_table VALUES (1, 2, 'carType', '"hatchback"');
INSERT INTO test_table VALUES (2, 1, 'carType', '"sedan"');
INSERT INTO test_table VALUES (2, 1, 'equipment', '["BB", "AA"]');
INSERT INTO test_table VALUES (3, 1, 'carType', '"hatchback"');
INSERT INTO test_table VALUES (3, 1, 'equipment', '["AT"]');

Edit:

Expected results - because I am going to compare arrays from two different tables, thus I would like to unify content of arrays, so '["AT", "AC"]' and '["AC", "AT"]' become the same. Frankly speaking, it doesn't matter which "default" sort is used: ASC or DESC - I will just have to run the same SQL query/procedure for two tables to make it consistent and comparable. Let's say that these are expected results:

INSERT INTO test_table VALUES (1, 1, 'carType', '"sedan"');
INSERT INTO test_table VALUES (1, 1, 'equipment', '["AC", "AT"]'); -- change here
INSERT INTO test_table VALUES (1, 2, 'extra', '["GPS"]');
INSERT INTO test_table VALUES (1, 2, 'carType', '"hatchback"');
INSERT INTO test_table VALUES (2, 1, 'carType', '"sedan"');
INSERT INTO test_table VALUES (2, 1, 'equipment', '["AA", "BB"]');  -- change here
INSERT INTO test_table VALUES (3, 1, 'carType', '"hatchback"');
INSERT INTO test_table VALUES (3, 1, 'equipment', '["AT"]');

回答1:


Use the function:

create or replace function jsonb_sort_array(jsonb)
returns jsonb language sql immutable as $$
    select jsonb_agg(elem order by elem)
    from jsonb_array_elements($1) elem
$$;

select *, 
    case jsonb_typeof(value_r)
    when 'array' then jsonb_sort_array(value_r)
    else value_r
    end as sorted_value
from test_table;

 id | ordinality |   key_r   |   value_r    | sorted_value 
----+------------+-----------+--------------+--------------
  1 |          1 | carType   | "sedan"      | "sedan"
  1 |          1 | equipment | ["AT", "AC"] | ["AC", "AT"]
  1 |          2 | extra     | ["GPS"]      | ["GPS"]
  1 |          2 | carType   | "hatchback"  | "hatchback"
  2 |          1 | carType   | "sedan"      | "sedan"
  2 |          1 | equipment | ["BB", "AA"] | ["AA", "BB"]
  3 |          1 | carType   | "hatchback"  | "hatchback"
  3 |          1 | equipment | ["AT"]       | ["AT"]
(8 rows)    

DbFiddle.



来源:https://stackoverflow.com/questions/51364401/jsonb-column-sort-only-content-of-arrays-stored-in-column-with-mixed-jsonb-cont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!