Postgresql

在 postgresql 中按鍵排序 json 項的巧妙方法(兩個範例)

  • December 28, 2020

我需要對記錄中的一個 json 項進行排序,所以這裡有兩個範例:

第一個案例

create table jsontable (
   jsonitem json
);

接下來我插入一個 json 項:

insert into jsontable(jsonitem) values ('{ "3" : "foo", "2" : "bar", "1" : "qux" }');

然後我查詢值:

select t.jsonitem from jsontable t;
                jsonitem                  
-------------------------------------------
{ "3" : "foo", "2" : "bar", "1" : "qux" }
(1 row)

假設密鑰是唯一的,並且是一個大於 0 的整數;

問題1: ¿如何將json項值按key值排序,得到如下?

{ "1" : "qux", "2" : "bar", "3" : "foo" }

第二種情況

這種情況下使用命名鍵和命名值。

create table jsontable_arr(
  jsonitem json
  );
insert into jsontable_arr(jsonitem) values ('[  { "key" : "3" , "value": "foo"}, { "key" : "2" , "value": "bar"}, { "key" : "1" , "value": "qux"} ]');
select t.* from jsontable_arr t;
                                               jsonitem
--------------------------------------------------------------------------------------------------------
[  { "key" : "3" , "value": "foo"}, { "key" : "2" , "value": "bar"}, { "key" : "1" , "value": "qux"} ]
(1 row)

問題2: ¿如何將json數組項按key值排序,得到如下?

[  { "key" : "1" , "value": "qux"}, { "key" : "2" , "value": "bar"}, {"key" : "3" , "value": "foo"} ]

感謝您的建議。

請注意,數組項的順序與JSON 對像中的鍵順序是不同的問題。看:

對於您的第一個範例(暗示整數排序),只需轉換為即可jsonb完成這項工作。預設情況下,它碰巧按照您想要的方式對鍵進行排序:

SELECT jsonitem::jsonb FROM jsontable;

db<>在這裡擺弄

或使用jsonb而不是json開頭。

但是,它不是嚴格的整數排序。鍵是字元串。較短的鍵在較長的鍵之前排序,這僅適用於數字。但不一定與其他任何東西。像負數一樣:

2, 3, -1

再說一次,您的解決方案會根據預設排序規則對字元串進行排序,即對不包含相同位數的數字進行整數排序:

111, 22, 3

你沒有具體說明。這將正確地進行整數排序:

select id, json_object_agg(key, value) AS jsonitem
from  (
  select id, key, value
  from   tbl
  ORDER  BY id, key::int  -- !!!
  ) tbl
group  by id;

當然,轉換為整數會為任何不是合法整數表示的字元串引發異常。

在子查詢中排序一次ORDER BY,因為這通常比從聚合函式中添加的每項排序要快得多。這是有效的,因為引用手冊

或者,從排序的子查詢中提供輸入值通常會起作用。

看:

你的第二個例子是一個不同的野獸,試圖通過(單個!?)嵌套鍵對包含 JSON 對象的數組進行排序。您可以像這樣重新排序數組:

SELECT j.id, arr.js_sorted
FROM   jsonarr j
CROSS  JOIN LATERAL (
  SELECT json_agg(value) AS js_sorted
  FROM (
     SELECT *
     FROM   json_array_elements(j.jsonitem)
     ORDER  BY (value-&gt;&gt;'key')::int  -- true integer sort!
     ) sub
  ) arr;

這實際上取決於您的值來自哪裡,它們可以是什麼,以及您希望如何準確排序。

引用自:https://dba.stackexchange.com/questions/282170