mysql 實現 上一行減去下一行


方法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經驗:逐步編寫最簡單的語句組成復雜的語句,逐步測試,才能邏輯清晰,調試容易

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM