查找PostgreSQL中的下一个最近的数字

时间:2013-07-07 19:14:18

标签: sql postgresql

我在Windows Server 2008 R2下使用PostGIS 2.0.3运行PostgreSQL 9.1.9 x64。

我有一张桌子:

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”和那个trench_id的“next”“from_m”之间的差异(在这个例子中以米为单位)。

所以,基于上面的数据,我想得到一个产生下表的查询:

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 个答案:

答案 0 :(得分:1)

以下是您如何获得差异,最后使用 one 上一个示例(如数据中所示,但未在文中明确说明)。

此处的逻辑是重复应用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,显示它正常工作。