PostgreSQL 9.5以上的版本中有了很多方便的操作符,使得操作 JSON 變得非常方便了。
一、 -> 和 ->> :
-> 表示獲取一個JSON數組元素,支持下標值(下標從0開始)、Key獲取。->> 表示獲取一個JSON對象字符串。
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON -> 1;
結果:
{"b":2}
以上,::JSON 表示聲明前面的字符串爲一個JSON字符串對象,而且PostgreSQL中的JSON、JSONB對象 Key的聲明必須是字符串 。同時,1表示獲取JSON數組中下標值爲1的JSON對象。
接下來,看下 ->> 的用法:
1 2 3 4 5 |
|
以上,->> 的查詢結果和 -> 對比不太直觀,我們可以進一步驗證。
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON -> 1 -> 'b';
結果:
2
以上,我們可以看到首先我們使用下標的方式,獲取JSON數組中下標值爲1的JSON對象 {"b":2}。然後,我們通過Key的方式來獲取這個JSON對象的Value值,結果是 2。
接下來,我們測試下 ->> 的方式來獲取:
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
報錯:
[SQL]SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
[Err] 錯誤: 操作符不存在: text -> unknown
LINE 1: SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
以上,可以看到錯誤提示操作符不存在,因爲第一步查詢出來的是一個字符串,不是JSON對象。當然,我們可以改造下這個查詢語句:
代碼:
SELECT ('[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1)::JSON -> 'b';
結果:
2
以上,可以看到現在可以正確查詢出結果,我們將第一步查詢出來的字符串轉成JSON對象,然後通過 Key 的方式來獲取 Value。不過,這種查詢方式相對於 -> 來說還是比較繁瑣的。
二、 #> 和 #>> :
在前一步,我們在一個JSON數組中可以使用 -> 下標值的方式來獲取一個JSON對象。但是,如果我們我們檢索的不是JSON數組,而是一個JSON對象中的JSON對象。很顯然,這種下標獲取的方式不再適用。不過,我們可以使用下面的方式來獲取。
#> 表示獲取指定路徑的一個JSON對象,#>>表示獲取指定路徑的一個JSON對象的字符串。
代碼:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON #> '{b}'
結果:
{"ba":"b1","bb":"b2"}
以上,我們使用 #> 方式來獲取一個JSON對象中的JSON對象。
注意:
在獲取一個JSON對象時,除非是JSON數組中的下標,必須要要用 { } 將JSON對象的 Key 包裹起來,否則會拋出異常。
代碼:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
結果:
[SQL]SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
[Err] 錯誤: 有缺陷的數組常量:"b"
LINE 1: SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
^
DETAIL: 數組值必須以 "{" 或者維度信息開始。
同樣的,我們還可以在 #> 的基礎上,繼續獲取這個JSON對象內的相關信息。
代碼:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'{b}'->'ba'
結果:
"b1"
以上,可以看到 -> 獲取的是一個JSON對象。->>是獲取的一個text 文本
以上是轉載內容 ,最後補上我的一個比較複雜的實操SQL
select com.company_name,to_char(bl_month,'yyyy-mm') month1,sum(((eb.eb_info::json->>'monitorEbFeeInfoTotal')::json->>'receivableFee')::numeric) as 總電費 ,
sum(((eb.eb_info::json->>'monitorEbFeeInfoTotal')::json->>'pmtFee')::numeric) as 總電度電費
,sum(((eb.eb_info::json->>'monitorEbFeeInfoTotal')::json->>'billPmt')::numeric) as 總計量電量 ,
sum(((eb.eb_info::json->>'monitorEbFeeInfoTotal')::json->>'baseFee')::numeric) as 基本電費 ,
sum(((eb.eb_info::json#>>'{ebInfos,2}')::json->>'totalPmt')::numeric) as 峯電量
,sum(((eb.eb_info::json#>>'{ebInfos,2}')::json->>'money')::numeric) as 峯電費 ,
sum(((eb.eb_info::json#>>'{ebInfos,3}')::json->>'totalPmt')::numeric) as 平電量
,sum(((eb.eb_info::json#>>'{ebInfos,3}')::json->>'money')::numeric) as 平電費 ,
sum(((eb.eb_info::json#>>'{ebInfos,4}')::json->>'totalPmt')::numeric) as 谷電量
,sum(((eb.eb_info::json#>>'{ebInfos,4}')::json->>'money')::numeric) as 谷電費
from EB_TARGET_MNT eb LEFT JOIN p_company com on eb.company_id=com.p_renter_id
LEFT JOIN c_target_monitor tar on eb.target_mnt_id=tar.c_target_monitor_id where
eb.del_flag=0 GROUP BY com.company_name,bl_month ORDER BY com.company_name,bl_month