2012-10-15 21 views
2

給定一個表示路徑的字符串列('/11/22/33/44'),如何返回給定數字後的下一個數字。從數組中獲取下一項

例如:

  • 給出一個id = 22,我想從路徑/11/22/33/44/返回33
  • 給出一個id = 44,我想從路徑/11/22/33/44/返回NULL

這是我使用的字符串轉換成一組記錄位:

SELECT unnest(string_to_array(trim(both '/' from '/11/22/33/44/'), '/')::integer[]); 
unnest 
-------- 
    11 
    22 
    33 
    44 
(4 rows) 

但如何獲得「下一入口」這裏(所以給定22 - >33)?

+0

我認爲數字在給定的路徑內是唯一的嗎? –

+0

不一定,但如果沒有更好的解決方案可用,則可以執行該操作。 –

+0

通常,使用分隔符將數據保存在字符串字段中不是數據庫中的方式。相反,我會保留一個路徑表,每個路徑的父指針,或沿着這些行的東西。 – perh

回答

2

一種方式是窗口函數:

SELECT a FROM (
    SELECT *, lag(a) OVER() AS lag_1 
    FROM unnest(string_to_array(trim(both '/' from '/11/22/33/44/'), '/')::integer[]) a 
) b WHERE lag_1 = 22; 

該解決方案返回零行的44輸入,但是這很容易通過調用它作爲一個子查詢解決。

或者,你可以使用intarray extensionidx功能整數數組:

CREATE EXTENSION intarray; 

WITH x(arr) AS (
    SELECT string_to_array(trim(both '/' from '/11/22/33/44/'), '/') :: integer[] 
) 
SELECT arr[idx(arr,22)+1] FROM x; 

查找下一個索引在數組中。 intarray是PostgreSQL發佈的擴展,它不是第三方附加組件。該解決方案對44產生NULL結果,無需進一步操作。

+0

你去 - '腿'功能!非常感謝! –

+0

@DmytriiNagirniak添加了基於替代陣列的解決方案 –

+0

感謝數組函數會更好,因爲我不需要'unnest',但不想向DB添加擴展。 –