使用非基于时间的开始和结束列查找表中的空白

时间:2017-08-01 16:31:55

标签: sql database postgresql

我需要根据双精度开始和结束列找到连续数据点中的间隙。

为简单起见,我们将其称为 startPoint endPoint ,它们会跟踪某一行的空间位置。 endPoint和startPoint之间的差异将指定一个距离。超过这个"距离"捕获特定的力/效果信号值,并基于值状态存储在表格上。每行都有一个唯一的 id 标识符。

因此,该表如下所示:

| id | startPoint | endPoint | state    |
|----|------------|----------|----------|
| 1  | 0.0        | 5.8      | Active   |
| 2  | 5.8        | 7.1      | Inactive |
| 3  | 7.5        | 10.2     | Inactive |
| 4  | 10.2       | 11.3     | Inactive |
| 5  | 11.6       | 12.1     | Active   |

我一直在努力想出一个可以在 PostgresSQL 中运行的查询,产生以下结果:

| startGap   | endGap   |
|------------|----------|
| 7.1        | 7.5      |
| 11.3       | 11.6     |

我很清楚我要做的就是将之前的endPoint与以下的startPoint进行比较,但到目前为止我没有运气。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

使用SQL Fiddle测试:http://sqlfiddle.com/#!9/2851c3/2/0(我显然认为这是因为某种原因的mySQL)

可能不是最有效的,因为必须为A中的每条记录运行子查询,而不是最大...

本质上,这是一个LEFT OUTER自连接以从A和B的起点获得终点,并且在找不到连接中的匹配时,我们识别出成为startgap的端点。然后我们使用子查询来查找该值

之上的最小起始点

我们排除了具有最高起点的最后一条记录,因为我们知道在最后一条记录之后找不到差距是没有意义的。

这假设没有数据重叠。

SELECT A.EndPoint as StartGap
     , (SELECT min(StartPoint) 
        FROM sqlfoo 
        WHERE StartPoint > A.EndPoint) as EndGap
FROM sqlfoo A
LEFT JOIN sqlfoo B 
 on A.EndPoint = B.StartPoint
WHERE B.StartPoint is null
  and A.StartPoint <> (SELECT max(startPoint) FROM sqlfoo)

这标识了最大开始

答案 1 :(得分:1)

使用窗口函数lead()

with my_table(id, startpoint, endpoint, state) as (
values
    (1, 0.0, 5.8, 'Active'),
    (2, 5.8, 7.1, 'Inactive'),
    (3, 7.5, 10.2, 'Inactive'),
    (4, 10.2, 11.3, 'Inactive'),
    (5, 11.6, 12.1, 'Active')
)

select *
from (
    select endpoint as startgap, lead(startpoint) over (order by startpoint) as endgap
    from my_table
    ) s
where startgap <> endgap;

 startgap | endgap 
----------+--------
      7.1 |    7.5
     11.3 |   11.6
(2 rows)