SQL:获取连续值的所有变异点

时间:2014-12-12 14:44:28

标签: sql postgresql join

我有一个经常采样的传感器值,因此对于多个样本,该值保持不变,即:

Date        Value
2010-01-01  1.345
2010-01-02  1.345
2010-01-03  1.555
2010-01-04  1.555
2010-01-05  1.555
2010-01-06  1.345
2010-01-07  1.752
2010-01-08  1.752

并希望得到价值变化的行:

Date        Value
2010-01-01  1.345
2010-01-03  1.555
2010-01-06  1.345
2010-01-07  1.752

一种选择是使用LAG窗口函数来获取每行的前一行(按日期排序)并比较当前/之前,但我想知道是否存在纯SQL解决方案。 我用自我外连接解决了这个问题

SELECT t1.date, t1.value
FROM table t1 LEFT OUTER JOIN table t2
ON t1.value = t2.value
AND t1.date > t2.date
WHERE t2.date IS NULL;

但是如果没有重复值,则只能,就像这里的情况一样,值为1.345

我必须补充说,不幸的是,日期值是唯一的,但通常不是等间距。

我目前正在使用PostgreSQL数据库,但我相信这个问题可以适用于任何系统。

2 个答案:

答案 0 :(得分:1)

通过使用排名并链接到前一天的数据,并仅在最后一天不等于第二天时显示。

DECLARE @t TABLE ([Date] DATE, Value DECIMAL(18,10))

INSERT INTO @t VALUES
('2010-01-01',  1.345),
('2010-01-02',  1.345),
('2010-01-03',  1.555),
('2010-01-04',  1.555),
('2010-01-05',  1.555),
('2010-01-06',  1.345),
('2010-01-07',  1.752),
('2010-01-08',  1.752)

SELECT 
    pDATA.[DATE],
    pDATA.[VALUE] 
FROM
    (SELECT 
        T2.[DATE],
        T2.VALUE , 
        RANK() OVER (ORDER BY T2.[DATE]) - 1 AS R2 
    FROM @T AS T2) AS pDATA 
    LEFT OUTER JOIN 
    (SELECT 
        T1.[DATE],
        T1.VALUE , 
        RANK() OVER (ORDER BY [DATE]
    ) AS R FROM @T AS T1) AS DATA

    ON DATA.R = pDATA.R2
WHERE 
    DATA.Value != pDATA.Value 
    OR DATA.Value IS NULL

答案 1 :(得分:0)

显示所有行,不包括那些值与前一行相同的行。

通过将每一行连接到具有较小日期的所有行并在该组较小日期中查找最大日期来查找上一行

在SQLIte中:

SELECT Date, Value, 0 FROM Readings
EXCEPT
SELECT y.Date, y.Value, ABS(y.Value- z.Value) AS Diff
FROM (SELECT a.Date AS au, Max(b.Date) AS bu FROM Readings AS a JOIN Readings AS b ON a.date>b.date  GROUP BY a.date) AS x --
JOIN Readings AS y ON y.Date=x.au --
JOIN Readings AS z ON z.Date=x.bu
WHERE Diff <.001