PostgreSQL JSON字段的 ->> #>> 取值操作

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}

 

以上,->> 的查詢結果和 -> 對比不太直觀,我們可以進一步驗證。

 

代碼:
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章