用等级替换子选择

时间:2014-05-21 15:58:16

标签: sql postgresql

为可怕的头衔道歉,我想不出现在更好的传达方式。

我的简化问题如下;

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

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

  • 阅读有时间戳。

我需要的是不良读数,检索最后已知的良好读数以及下一次良好的阅读。

这样做的一个简单方法是使用子选择;

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' `

SQL小提琴;

http://sqlfiddle.com/#!15/3aedd/10

但是对于我的(相当大的)数据集来说,这是非常缓慢的。我有一种感觉,我可以通过使用postgresql的一个排名功能来做到这一点,但我无法理解它,因为我不知道有多少连续的坏读数,然后我才能获得良好的阅读。

1 个答案:

答案 0 :(得分:1)

这样更好吗?

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;