Postgresql
在 postgresql 中按鍵排序 json 項的巧妙方法(兩個範例)
我需要對記錄中的一個 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->>'key')::int -- true integer sort! ) sub ) arr;
這實際上取決於您的值來自哪裡,它們可以是什麼,以及您希望如何準確排序。