值更改时SELECT sql行

时间:2015-06-08 12:01:55

标签: mysql sql

我遇到了SQL查询问题。

我正在使用MariaDB。我有一个包含多个字段的表,我想在更改值时选择行。

例如:

+------------+----------+----------+
| time_stamp | G1.state | G2.state |
+------------+----------+----------+
| 1433717821 | 3        | 1        |
+------------+----------+----------+
| 1433717881 | 3        | 1        |
+------------+----------+----------+
| 1433717942 | 5        | 1        |
+------------+----------+----------+

这里我需要在3次更改为5时获取time_stamp。我已尝试过以下查询:

SELECT a.`time_stamp`, a.`G1.state`, `G2.state` 
FROM `regs` AS `a` 
WHERE ((a.`G1.Estado` <> 
    (SELECT b.`G1.state` 
     FROM `regs` AS `b` 
     WHERE a.time_stamp > b.time_stamp 
     ORDER BY b.time_stamp DESC 
     LIMIT 1)) OR
   (a.`G2.state` <>
    (SELECT b.`G2.state`
     FROM `regs` AS `b`
     WHERE a.time_stamp > b.time_stamp 
     ORDER BY b.time_stamp DESC 
     LIMIT 1))) AND
    (a.time_stamp >= 1433159549) AND (a.time_stamp < 1433677949)
ORDER BY a.time_stamp ASC

然而,运行时间太长,需要50.96秒,而且我需要它更快(希望不到一秒钟)。它分析大约10k的值。谁能帮我一把?

3 个答案:

答案 0 :(得分:2)

您可以使用变量来跟踪G1.stateG2.state列中的更改:

SELECT time_stamp, `G1.state`, `G2.state`
FROM (
SELECT time_stamp, `G1.state`, `G2.state`,
       IF (@g1 IS NOT NULL AND @g1 <> `G1.state`, 
           IF(@g1:= `G1.state`, 1, 1), 
           IF(@g1:= `G1.state`, 0, 0)) AS g1Changed,
       IF (@g2 IS NOT NULL AND @g2 <> `G2.state`, 
           IF(@g2:= `G2.state`, 1, 1), 
           IF(@g2:= `G2.state`, 0, 0)) AS g2Changed           
FROM mytable, (SELECT @g1:= NULL, @g2:= NULL) AS vars
ORDER BY time_stamp ASC ) t
WHERE g1Changed = 1 OR g2Changed = 1

此查询可能表现更好,因为没有使用相关的子查询。

注意:根据MariaDB documentation

  

读取用户定义的变量并在同一语句中设置其值是不安全的(除非该命令是SET),因为这些操作的顺序是未定义的。

要解决此问题,请使用嵌套条件:@g1@g2 首先分别与G1.stateG2.state值进行比较,并且<设置em> then ,以便在获取下一条记录时再次进行比较。

Demo here

答案 1 :(得分:0)

Select * from regs a
Where time_stamp=
     (Select Max(time_stamp) from regs
      Where time_stamp< a.time_stamp)
  and 'g1.state' <> a.'g1.staTE'
order by a.time_stamp

答案 2 :(得分:0)

您可以使用索引加快查询速度。最好的指标是

regs(time_stamp, `G1.state`, `G2.state`)

注意:在列名中使用.等字符是真的不良做法。