2017-04-24 57 views
0

我在Windows上使用PostgreSQL 9.4.5,64位。 我有一些不規則大小的數組。我想用 json_array_elements擴大類似下面的代碼陣列json_array_elements空值

with outside as (select (json_array_elements('[[],[11],[21,22,23]]'::json)) aa, json_array_elements('[1,2,3]'::json)bb) 
select json_array_elements_text(aa), bb from outside 

然而,當我運行它,我得到

aa | bb 
------- 
11 | 2 
21 | 3 
22 | 3 
23 | 3 

列AA空數組在地板上而下降在列的BB的值1

我想獲得

aa | bb 
---------- 
null | 1 
11 | 2 
21 | 3 
22 | 3 
23 | 3 

另外,這是PostgreSQL中的錯誤嗎?

回答

1

您使用的是正確的功能,但錯誤JOIN。如果你(可能)沒有對你想保留的行從JOIN &使用對方NULL s到「墊」行JOIN &一面行,你需要一個OUTER JOIN

with outside as (
    select json_array_elements('[[],[11],[21,22,23]]') aa, 
      json_array_elements('[1,2,3]') bb 
) 
select a, bb 
from  outside 
left join json_array_elements_text(aa) a on true 

:它可能似乎很奇怪,看on true作爲加入條件,但它實際上是相當普遍的,當您使用LATERAL joins(當你使用一組返回功能(SRF這是隱含的)直接在條款FROM條款)。

http://rextester.com/KNW13145

編輯:原始查詢不涉及JOIN直接,但糟糕的是:你的SELECT子句中使用SRF。這幾乎是CROSS JOIN,但實際上it has its own rulesDon't use that除非你確切地知道你在做什麼,爲什麼你需要這樣做。

+0

謝謝 - 很好的答案,並且左連接更清潔,那麼klin的case語句 – newman911

1

這不是一個錯誤。 json_array_elements_text('[null]')返回nulljson_array_elements_text('[]')不返回任何內容。

with outside as (
    select (
     json_array_elements('[[],[11],[21,22,23]]'::json)) aa, 
     json_array_elements('[1,2,3]'::json) bb 
) 
select elem as aa, bb 
from outside, 
json_array_elements_text(case when aa::text = '[]' then '[null]'::json else aa end) elem; 

aa | bb 
----+---- 
    | 1 
11 | 2 
21 | 3 
22 | 3 
23 | 3 
(5 rows)  
+0

我同意json_array_elements_text正如你所描述的那樣工作,爲什麼這種正確的行爲? – newman911

+0

因爲''[null]':: json'和''[]':: json'之間有區別。第一個數組包含null,第二個數組爲空。該函數不能從空數組中返回任何東西。 – klin

0

通過我自己的問題的工作,我已經得到了一個可能的答案,但它似乎是一個爛攤子

With initial as (select '[[],[11],[21,22,23]]'::json as a, '[1,2,3]'::json as b), 
    Q1 as (select json_array_elements(a) as aa, json_array_elements(b) bb from initial), 
    Q2 as (select ARRAY[aa->>0, aa->>1, aa->>2] as aaa, bb as bbb, ARRAY[0,1,2] as ccc from q1), 
    -- where the indicices are computed in a separate query by looping from 0 to json_array_length(...) 
    Q3 as (select unnest(aaa) as aaaa, bbb as bbbb, unnest(ccc) as cccc from q2) 

Select aaaa, bbbb from q3 where aaaa is not null or cccc = 0