2015-11-16 45 views
1

我希望做一些操作存儲在PostgreSQL 9.4 JSON格式的數字。假設我有這張表:如何計算嵌套在PostgreSQL JSON號碼?

CREATE TABLE t (id SERIAL, a JSON); 

INSERT INTO t (a) 
VALUES ('[[0.1, 2.0], [0.3, 4.0], [0.5, 6.0]]'), 
     ('[[0.7, 8.0], [0.9, 10.0]]'); 

所以我可以用例如json_array_elements()

SELECT id, json_array_elements(a) AS sub1 FROM t; 

id | sub1 
---------------- 
1 | [0.1, 2.0] 
1 | [0.3, 4.0] 
1 | [0.5, 6.0] 
2 | [0.7, 8.0] 
2 | [0.9, 10.0] 

請注意,元素的數量可能會有所不同。現在,我希望做一些計算與子元素,如:

SELECT id, 
     ((json_array_elements(a)->>0)::FLOAT) * 
     ((json_array_elements(a)->>1)::FLOAT) as result 
FROM t 

但是我得到的錯誤:ERROR: functions and operators can take at most one set argument。任何提示?

回答

3

使用一個(隱含的)LATERAL join代替:

SELECT id, (e->>0)::float * (e->>1)::float as result 
FROM t, json_array_elements(a) e 

設置,返回在SELECT作品的功能非常特殊的PostgreSQL中:

的y的確切原因我們的錯誤是,你試圖乘以兩套(這是不允許的)。的PostgreSQL可以計算<element> * <element>(將是單值),​​(或反之亦然;將設置值),但不<set> * <set>

+0

出色答卷! – n1000

1

這是因爲json_array_elements()回報SETOF JSON。

你應該路徑更好地進入的元素,像這樣:

SELECT 
     id, 
     (a#>>'{0,0}')::float * (a#>>'{0,1}')::float as result 
    FROM processing.t; 

而且有關錯誤是here

如果這不是一個選項,你可以使用子查詢:

select 
     id, 
     (a->>0)::float * (a->>1)::float as result 
    from (
     SELECT 
       id, 
       json_array_elements(a) as a 
      FROM processing.t 
    ) t; 

在這種情況下,你可以編寫表達式,你想要的方式。

+0

謝謝!這是一個很好的答案。但實際上我不知道有多少物品會嵌套在第一個元素中。所以我需要一個更靈活的解決方案。我會盡力更新我的問題。 – n1000