2013-07-07 80 views
3

我在Windows Server 2008 R2下運行PostgreSQL 9.1.9 x64和PostGIS 2.0.3。在PostgreSQL中查找下一個最接近的號碼

我有一個表:

CREATE TABLE field_data.trench_samples (
    pgid SERIAL NOT NULL, 
    trench_id TEXT, 
    sample_id TEXT, 
    from_m INTEGER 
); 

隨着一些數據吧:

INSERT INTO field_data.trench_samples (
    trench_id, sample_id, from_m 
) 
VALUES 
    ('TR01', '1000001', 0), 
    ('TR01', '1000002', 5), 
    ('TR01', '1000003', 10), 
    ('TR01', '1000004', 15), 
    ('TR02', '1000005', 0), 
    ('TR02', '1000006', 3), 
    ('TR02', '1000007', 9), 
    ('TR02', '1000008', 14); 

現在,我是一個與感興趣的是找出(在本例爲米的距離)的區別記錄的「from_m」和「next」「from_m」表示該trench_id。

因此,基於上述數據,我想與產生如下表查詢來結束:

pgid, trench_id, sample_id, from_m, to_m, interval 
1, 'TR01', '1000001', 0, 5, 5 
2, 'TR01', '1000002', 5, 10, 5 
3, 'TR01', '1000003', 10, 15, 5 
4, 'TR01', '1000004', 15, 20, 5 
5, 'TR02', '1000005', 0, 3, 3 
6, 'TR02', '1000006', 3, 9, 6 
7, 'TR02', '1000007', 9, 14, 5 
8, 'TR02', '1000008', 14, 19, 5 

現在,你可能會說:「等一下,我們如何推斷出的間隔每行最後一個樣本的長度,因爲沒有「next」from_m來比較?「

對於行的「結尾」(sample_id 1000004和1000008),我想使用前兩個樣本的相同區間長度。

當然,我不知道如何在我目前的環境中解決這個問題。非常感激你的幫助。

回答

1

下面是你如何得到的差異,使用一個前面的例子在最後(如數據所示,但在文本中沒有解釋清楚)。

這裏的邏輯是重複應用lead()lag()。首先應用lead()來計算間隔。然後應用lag()來計算邊界處的間隔,使用前一個間隔。

剩下的基本上就是算術:

select trench_id, sample_id, from_m, 
     coalesce(to_m, 
       from_m + lag(interval) over (partition by trench_id order by sample_id) 
       ) as to_m, 
     coalesce(interval, lag(interval) over (partition by trench_id order by sample_id)) 
from (select t.*, 
      lead(from_m) over (partition by trench_id order by sample_id) as to_m, 
      (lead(from_m) over (partition by trench_id order by sample_id) - 
       from_m 
      ) as interval 
     from field_data.trench_samples t 
    ) t 

Here是顯示其工作SQLFiddle。

+0

非常感謝您的快速響應!你使用row_number的原因是什麼,而不是僅僅使用插入的pgid中存儲的值? – Joebocop

+1

@Joebocop。 。 。沒有任何理由。當我回答時,我錯過了「序列號」。 –

+0

@Joebocop。 。 。窗口/分析函數是許多數據庫支持的非常強大的函數。很高興你有機會了解他們。 –