mysql - SQL:选择列值从上一行更改的行

标签 mysql sql

假设我有这个(MySQL)数据库,按时间戳递增排序:

Timestamp   System StatusA StatusB 
2011-01-01     A      Ok     Ok      
2011-01-02     B      Ok     Ok     
2011-01-03     A     Fail   Fail     
2011-01-04     B      Ok    Fail     
2011-01-05     A     Fail    Ok      
2011-01-06     A      Ok     Ok      
2011-01-07     B     Fail   Fail    

对于该系统,如何选择 StatusA 从上一行更改的行? StatusB 无关紧要(我在这个问题中展示它只是为了说明每个系统可能有许多连续的行,而 StatusA 不会改变)。在上面的示例中,查询应返回 2011-01-03 行(对于 SystemA,StatusA 在 2011-01-01 和 2011-01-03 之间更改)、2011-01-06、2011-01-07。

查询应该在具有数万条记录的表中快速执行。

谢谢

最佳答案

SELECT a.*
FROM tableX AS a
WHERE a.StatusA <>
      ( SELECT b.StatusA
        FROM tableX AS b
        WHERE a.System = b.System
          AND a.Timestamp > b.Timestamp
        ORDER BY b.Timestamp DESC
        LIMIT 1
      ) 

但是你也可以试试这个(在 (System,Timestamp) 上有一个索引:

SELECT System, Timestamp, StatusA, StatusB
FROM
  ( SELECT (@statusPre <> statusA AND @systemPre=System) AS statusChanged
         , System, Timestamp, StatusA, StatusB
         , @statusPre := StatusA
         , @systemPre := System
    FROM tableX
       , (SELECT @statusPre:=NULL, @systemPre:=NULL) AS d
    ORDER BY System
           , Timestamp
  ) AS good
WHERE statusChanged ;

关于mysql - SQL:选择列值从上一行更改的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6560000/

相关文章:

php - 我可以通过 1 个查询来完成此操作吗?

mysql - 如何在1096​​列中存储数据

sql - 将 SQL 结果集划分为 block

sql - BULK INSERT 0 受影响的行

sql - 合并两个表的内容而不重复内容

sql - Teradata 连接多个字符串列格式作为时间戳

python - 如何在所有外键之后执行 SELECT *

php - 父类别未显示在列表中

mysql - INSERT INTO 在 PROCEDURE 中不起作用

mysql - SQL 一对多关系 - 如何根据多个对多属性来选择行?