2013-03-02 78 views
10

我使用postgreSQL 9.1。在我的數據庫中有一個表,看起來像PostgreSQL與空陣列unnest

id | ... | values 
----------------------- 
1 | ... | {1,2,3} 
2 | ... | {} 

其中id是一個整數,值是一個整數數組。數組可以是空的。

我需要不要這個名單。如果我查詢

select id, ..., unnest(values) 
from table 

我得到ID三行= 1(預期)和ID = 2,沒有臺詞有沒有辦法讓像

id | ... | unnest 
------------------- 
1 | ... | 1 
1 | ... | 2 
1 | ... | 3 
2 | ... | null 

即查詢的結果,其還包含具有空數組的行嗎?

回答

9
select id, 
     case 
     when int_values is null or array_length(int_values,1) is null then null 
     else unnest(int_values) 
     end as value 
from the_table; 

(請注意,我改名列valuesint_values作爲values是保留字,不應該被用來作爲列名)。

SQLFiddle:http://sqlfiddle.com/#!1/a0bb4/1


Postgres的10不允許使用unnest()這樣了。

您需要使用橫向聯接:

select id, t.i 
from the_table 
    cross join lateral unnest(coalesce(nullif(int_values,'{}'),array[null::int])) as t(i); 

在線例如:http://rextester.com/ALNX23313

+0

這不適用於Postgresql 10 – 2018-02-21 17:40:31

+0

@BleedingFingers:看到我的更新 – 2018-02-21 17:50:01

0

您將需要使用自LEFT JOIN,像這樣的(也SQL Fiddle):

SELECT t.id, u.u 
    FROM tab t 
    LEFT JOIN (SELECT id, unnest(vals) u FROM tab) u 
    USING (id); 

注意,對於更大的表查詢將被執行得很厲害。

1
select id, 
    unnest (
     "values" 
     || 
     (array[null]::integer[])[1:(array_upper("values", 1) is null)::integer] 
    ) 
from "table" 
3

在重新審視這個問題,我突然想到,這可能是簡單,速度更快。
反轉currently accepted solution by @a_horse的邏輯:

SELECT id, CASE WHEN values <> '{}' THEN unnest(values) END AS value 
FROM tbl 
  • 此方法返回NULL一個行中value用於空數組以及用於NULL陣列,因爲只有在元素的數組它在測試values <> '{}'中產生TRUE

  • 適用於任意類型的數組,因爲文字'{}'被自動強制爲匹配類型。

  • 沒有明確的ELSE分支,CASE返回NULL,這正是我們想要的。

  • 具有NULL元素的數組將返回行,無論如何。
    然而,我發現了一個異常那裏發佈關於該問題:

    原來是這是我的第9.3+報告後,修正了一個錯誤。