Sql 用秩替换子选择

Sql 用秩替换子选择,sql,postgresql,Sql,Postgresql,为这个糟糕的标题道歉,我现在想不出更好的表达方式了 我的简化问题如下 想象一下,每天将读数输入表格 阅读可以是好的,也可以是坏的 读数有时间戳 我需要的是对于错误的阅读,检索上一个已知的好阅读和下一个好阅读 一个简单的方法是使用子选择 SELECT TIMESTAMP AS badreading ,( SELECT TIMESTAMP FROM dailyreading dailyreading_2 WHERE dailyreading_2

为这个糟糕的标题道歉,我现在想不出更好的表达方式了

我的简化问题如下

想象一下,每天将读数输入表格

阅读可以是好的,也可以是坏的

读数有时间戳

我需要的是对于错误的阅读,检索上一个已知的好阅读和下一个好阅读

一个简单的方法是使用子选择

SELECT TIMESTAMP AS badreading
    ,(
        SELECT TIMESTAMP
        FROM dailyreading dailyreading_2
        WHERE dailyreading_2.result = 'Good'
            AND dailyreading_2.TIMESTAMP < dailyreading.TIMESTAMP
        ORDER BY dailyreading_2.TIMESTAMP DESC LIMIT 1
        ) previousGoodReading
    ,(
        SELECT TIMESTAMP
        FROM dailyreading dailyreading_2
        WHERE dailyreading_2.result = 'Good'
            AND dailyreading_2.TIMESTAMP > dailyreading.TIMESTAMP
        ORDER BY dailyreading_2.TIMESTAMP ASC LIMIT 1
        ) nextGoodReading
FROM dailyreading
WHERE result = 'Bad' `
在这里摆弄

但这对于我相当大的数据集来说是非常缓慢的。我有一种感觉,我可以使用postgresql的一个排名功能来实现这一点,但我无法控制它,因为我不知道在我获得好的阅读之前,有多少连续的坏阅读。

这样更好吗

SELECT d1.timestamp as badreading
    ,  max(case when d2.timestamp < d1.timestamp then d2.timestamp end) as x
    ,  min(case when d2.timestamp > d1.timestamp then d2.timestamp end) as y  
FROM dailyreading d1, dailyreading d2
WHERE d1.result = 'Bad'
  AND d2.result = 'Good'
GROUP BY d1.timestamp
ORDER BY d1.timestamp;

听起来你在寻找超前和滞后: