方法1 :通過行號來進行加減
1.新建表1添加自增行號列(考慮到自增id 有丟失數據現象)
2.復制上表1為表2
3.根據表1、表2行號進行where或者left join on的處理
* where 進行處理的條件為表1表2完全的匹配
*left join on 處理的條件為 左表完全的匹配
#設置內存變量
SET @arownum=0;
SET @brownum=0;
#查詢sql
SELECT a.id ,a.terminal_id,a.TIMESTAMP,a.seq-b.seq FROM
( SELECT @arownum:=@arownum+1 AS id ,terminal_id,TIMESTAMP,seq FROM `msg_basic` ORDER BY terminal_id, TIMESTAMP )AS a
LEFT JOIN
( SELECT @brownum:=@brownum+1 AS id ,terminal_id,TIMESTAMP,seq FROM `msg_basic` ORDER BY terminal_id, TIMESTAMP )AS b
ON a.id = b.id+1
#也可新建表
CREATE TABLE tab2 AS SELECT @brownum:=@brownum+1 AS id ,terminal_id,TIMESTAMP,seq FROM `msg_basic` ORDER BY terminal_id, TIMESTAMP
方法1優化:
優化原因1:方法1中的a.id = b.id+1進行查詢速度很慢(1min以上),但a.id = b.id進行查詢的速度很快;於是開始想到update id (UPDATE tabname SET id =id-1 測試可行 ;)
優化原因2:消息序列在篩選時容易出現terminal_id 不一致現象,所以增加條件
優化原因3,查看計算結果的過程明細
優化后語句:
SET @arownum=0;
SET @brownum=1;
#查詢sql
SELECT a.id ,b.id,a.terminal_id,a.TIMESTAMP,b.TIMESTAMP,a.seq,b.seq ,a.seq-b.seq AS dseq FROM
( SELECT @arownum:=@arownum+1 AS id ,terminal_id,TIMESTAMP,seq FROM `msg_basic` ORDER BY terminal_id, TIMESTAMP )AS a,
( SELECT @brownum:=@brownum+1 AS id ,terminal_id,TIMESTAMP,seq FROM `msg_basic` ORDER BY terminal_id, TIMESTAMP )AS b
WHERE a.id = b.id AND a.terminal_id=b.terminal_id #篩選設備相同、seq差距為1
AND a.seq-b.seq>1 #根據消息序號進行篩選,丟失消息數量需要大於1,如果連續則為1
AND LEFT(b.TIMESTAMP,6)=LEFT(a.TIMESTAMP,6)#篩選日期相同的,進行消息包減法
AND CAST(a.seq AS SIGNED INTEGER) > 12 #排除熄火后重新點火后seq變為1
AND CAST(a.timestamp AS SIGNED INTEGER) > 180201095138 #排除 18-02-01之前的數據
AND a.terminal_id <> '01020408101F' # 排除設備編號為01020408101F
方法2:通過limit不能實現原因
前提 t1=[2-6]5個數字,t2:=[1:6] 6個數字 ,t1為t2刪去一行
因為mysql的相減 必須通過 where 條件找到共同的條件,類似於t1.id= t2.id;直接讓其相減則能夠得到, 5*6=30個結果;
寫sql經驗:逐步編寫最簡單的語句組成復雜的語句,逐步測試,才能邏輯清晰,調試容易
