保留最新的一个字段值,直到它发生变化,然后保持其最新的字段值

时间:2018-02-14 21:11:58

标签: mysql sql

我有几张表有数百万条记录,其中传感器正在发送多个01值,并且这些数据已记录到表中,即使我们只需要保留第一个每1010更改01

已经进行了调整,因此我们现在只在每次更改时获得10值,而不是每一秒或其他任何值,但我需要从表中清除不必要的记录。

enter image description here

我已经完成了一些研究和测试,我无法确定在这里使用哪种方法来删除不需要的记录。我试图弄清楚如何使用变量保留以前的值记录,并创建行号,但它不能正常工作。

我在这里创建了一个SQLFiddle,并根据示例帖子MySQL - How To Select Rows Depending on Value in Previous Row (Remove Duplicates in Each Sequence)尝试了一些逻辑。我一直没有得到这样的结果,当我尝试在大型本地MySQL表上运行它时,我得到一个错误,我必须增加 MySQL Workbench 读取查询超时600或失去联系。

我还找到了“MySql - How get value in previous row and value in next row?”帖子,并尝试了它的一些变体以及“How to get next/previous record in MySQL?”,我得出了完全失败的预期结果。

数据

表格中的数据有一个TimeStr列和一个Value列,就像在屏幕截图中一样,在 SQLFiddle 链接上,我发布了一小段样本数据。

每个记录永远不会有相同的TimeStr值但是当传感器转为 ON OFF 如果这澄清了。

我不确定记录是否需要添加增量行号以获得预期结果,因为它只有TimeStrValue记录。

我的问题

任何人都可以帮我确定一个方法,我可以在几个大表上使用这些方法从表中删除后续和重复Value值的记录,这样表只有第一个{{1}或1记录实际从0变为100的位置?

我会接受一个答案,这个答案也会产生所需的记录 - 但任何表现得很快的人都会更加欣赏。

  • 我可以轻松地将它们放入临时表中,删除原始表,然后创建所需记录并将其插入原始表中。

预期结果

1

3 个答案:

答案 0 :(得分:1)

试试这个:

    SET @rownum = 0; 
SET @rownum_x = 0; 
SELECT b.rownum, b.TimeStr, b.Value
FROM 
(
    SELECT @rownum := @rownum+1 as rownum, TimeStr, Value
    FROM sensor
    ORDER BY TimeStr
) b
LEFT JOIN (
    SELECT @rownum_x := @rownum_x+1 as rownum_x, TimeStr as TimeStr_x, Value as Value_x
    FROM sensor
    ORDER BY TimeStr
) x ON b.rownum = x.rownum_x + 1
where b.Value <> x.Value_x or x.Value_x is null
order by b.TimeStr

我得到的结果是 enter image description here

答案 1 :(得分:1)

每个值出现时,您需要第一条记录。这表明变量。这是一种只涉及排序和不加入的方式:

select t.*
from (select t.*,
             (case when value = @prev_value then value
                   when (@save_prev := @prev_value) = NULL then NULL 
                   when (@prev_value := value) = NULL then NULL
                   else @save_prev
              end) as prev_value
      from (select t.*
            from sensor t
            order by timestr
           ) t cross join
           (select @prev_value := -1) params
     ) t
where prev_value <> value;

注意:

  • 自MySQL 5.7以来,似乎只需要用于排序的子查询。
  • case只是引入序列化代码的一种方式。使用变量时,它只应用于一个表达式。
  • 这只需要一种 - 如果你有一个索引,那么它甚至不需要排序。

Here是一个SQL小提琴。

答案 2 :(得分:1)

Select t.timestr, t.value from (
 SELECT s.*,  @pv x1, (@pv := s.value) x2
 FROM sensor S, (select @pv := -1) x
 ORDER BY TimeStr ) t
where t.x1 != t.x2 

请参阅http://sqlfiddle.com/#!9/8d0774/122