我有一个经常采样的传感器值,因此对于多个样本,该值保持不变,即:
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数据库,但我相信这个问题可以适用于任何系统。
答案 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