2011-08-05 55 views
7

我在PostgreSQL(PLPGSQL)中有一個函數,它返回一個包含兩個元素的數組。當我運行一個select語句調用函數,我得到一個包含數組的列(如預期):PostgreSQL將函數返回的數組轉換爲列

{1, 2} 

我真的想什麼做的是提取這些元素是自己列:

[ 1 | 2 ] 

我發現,我可以這樣做:

SELECT (MyFunction())[1], (MyFunction())[2] 

但調用該函數兩次,因此倍增運行時間(此功能是一個非常耗時的功能)。有沒有更好的方法來處理這個問題?


UPDATE

這裏是什麼,我有一個近乎完美的翻版:

SELECT table1.a, table1.b, table1.c, (MyFunction(table1.a, table1.b, table1.c))[1], 
(MyFunction(table1.a, table1.b, table1.c))[2] 
FROM table1 
INNER JOIN table2 using(b) 
WHERE ... GROUP BY table1.a, table1.b, table1.c; 

再次,這將產生兩列從陣列中,但我的函數被調用了兩次,這使我的運行時間翻了一番。

+0

我會注意到,返回數組中元素的數量始終是2 ... – lightningmanic

+0

如果返回的結果的形狀是已知的,你應該返回一個數組呢?那應該可能是一排。你有能力重構嗎? – SingleNegationElimination

回答

7

你可以使用子選擇嗎?

postgres=# select ar[1], ar[2] from (select string_to_array('a b c', ' ') ar) as sq; 
ar | ar 
----+---- 
a | b 
(1 row) 

這仍然需要你明確地提取每一列(就像你已經做過的那樣)。如果數組中的元素多於提取的元素,則它們將丟失,如果數量較少,則丟失的列將僅爲NULL

編輯:我想我會包裹在一個子選擇整個事情;內再選擇產生期望,與外選擇內部查詢伸入所需

SELECT subquery1.a, subquery1.b, subquery1.c, 
    myfunction_result[1], myfunction_result[2] 
FROM (SELECT table1.a, table1.b, table1.c, 
       MyFunction(table1.a, table1.b, table1.c) as myfunction_result 
     FROM table1 INNER JOIN table2 using(b) 
     WHERE ... GROUP BY table1.a, table1.b, table1.c 
) AS subquery1; 

內外選擇將正確的table1引用相關。

+0

這是通常的「局部變量」技巧之一,只要數組中元素的數量是固定的,它就應該工作。 –

+0

唯一的問題(也許我應該在前面提到過)是函數依賴於相同查詢級別的其他關係。所以我選擇「table_id」,並將相同的id傳遞給函數。 – lightningmanic

+0

@mu太短:根本不是真的。請參閱編輯。 – SingleNegationElimination

2

你不能那樣做。例如,一個數組列可以有一個數組,其中有三個元素,另一個數組有五個元素。如果 您試圖將這些數組展開爲單個列,那麼結果集中的兩行將結束 ,這兩行的列數不同,但不允許使用 列。

提供最接近的事是unnest

expand an array to a set of rows

但給你,而你想要的列行。

2
select data[1] as id, data[2] as value from (SELECT 
string_to_array(rs,':') as data from unnest(string_to_array('1:234,2:400',',')) as rs) as foo 

這將導致爲:

id|Value 
-------- 
1 | 234 
2 | 400 
相關問題