对此进行调查,以下方法可能是比您已经使用的更快的基本选择方法:-
SELECT AfterSub.ID,
AfterSub.SerialNumber,
BeforeSub.Remain_Toner_Black BeforeCount,
AfterSub.Remain_Toner_Black AfterCount
FROM
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter1:=@Counter1+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter1:=0) Sub1
ORDER BY SerialNumber, ID
) AfterSub
INNER JOIN
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter2:=@Counter2+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter2:=1) Sub2
ORDER BY SerialNumber, ID
) BeforeSub
ON BeforeSub.SerialNumber = AfterSub.SerialNumber
AND BeforeSub.SeqCnt = AfterSub.SeqCnt
WHERE AfterSub.Remain_Toner_Black > BeforeSub.Remain_Toner_Black
ORDER BY AfterSub.SerialNumber, AfterSub.ID
在这里检查月份的问题是以下项目可能在不同的月份,这取决于计数。
你可以试试:-
SELECT AfterSub.ID,
AfterSub.SerialNumber,
BeforeSub.Remain_Toner_Black BeforeCount,
AfterSub.Remain_Toner_Black AfterCount
FROM
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter1:=@Counter1+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter1:=0) Sub1
ORDER BY SerialNumber, ID
) AfterSub
INNER JOIN
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter2:=@Counter2+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter2:=1) Sub2
ORDER BY SerialNumber, ID
) BeforeSub
ON BeforeSub.SerialNumber = AfterSub.SerialNumber
AND BeforeSub.SeqCnt = AfterSub.SeqCnt
AND AfterSub.Remain_Toner_Black > BeforeSub.Remain_Toner_Black
WHERE month(BeforeSub.Time) = ".$i."
ORDER BY AfterSub.SerialNumber, AfterSub.ID
但这不会使用索引(但我希望行数很低,所以我希望不是问题)。
您可以选择获取序列号,然后只检查该月的项目,然后再加入下个月:-
SELECT AfterSub.ID,
AfterSub.SerialNumber,
BeforeSub.Remain_Toner_Black BeforeCount,
AfterSub.Remain_Toner_Black AfterCount
FROM
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter1:=@Counter1+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter1:=0) Sub1
ORDER BY SerialNumber, ID
) AfterSub
INNER JOIN
(
SELECT ID, SerialNumber, Remain_Toner_Black, SeqCnt
FROM
(
SELECT ID, SerialNumber, Remain_Toner_Black, `Time`, @Counter2:=@Counter2+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter2:=1) Sub2
ORDER BY SerialNumber, ID
) BeforeSub
WHERE month(BeforeSub.Time) = ".$i."
) BeforeSub
ON BeforeSub.SerialNumber = AfterSub.SerialNumber
AND BeforeSub.SeqCnt = AfterSub.SeqCnt
AND AfterSub.Remain_Toner_Black > BeforeSub.Remain_Toner_Black
ORDER BY AfterSub.SerialNumber, AfterSub.ID
(注意,最后 2 个选择都没有经过测试)
编辑
为 2 个子选择添加年/月检查。但是,由于日期被格式化以进行此检查,我不确定索引是否有用:-
SELECT AfterSub.ID,
AfterSub.SerialNumber,
BeforeSub.Remain_Toner_Black BeforeCount,
AfterSub.Remain_Toner_Black AfterCount
FROM
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter1:=@Counter1+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter1:=0) Sub1
WHERE DATE_FORMAT(`Time`,'%Y %m') >= '2013 01'
ORDER BY SerialNumber, ID
) AfterSub
INNER JOIN
(
SELECT ID, SerialNumber, Remain_Toner_Black, `Time`, @Counter2:=@Counter2+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter2:=1) Sub2
WHERE DATE_FORMAT(`Time`,'%Y %m') = '2013 01'
ORDER BY SerialNumber, ID
) BeforeSub
ON BeforeSub.SerialNumber = AfterSub.SerialNumber
AND BeforeSub.SeqCnt = AfterSub.SeqCnt
AND AfterSub.Remain_Toner_Black > BeforeSub.Remain_Toner_Black
ORDER BY AfterSub.SerialNumber, AfterSub.ID
在子选择中使用日期(这意味着计算该月的最后一天)可能更有效:-
SELECT AfterSub.ID,
AfterSub.SerialNumber,
BeforeSub.Remain_Toner_Black BeforeCount,
AfterSub.Remain_Toner_Black AfterCount
FROM
(
SELECT ID, SerialNumber, Remain_Toner_Black, @Counter1:=@Counter1+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter1:=0) Sub1
WHERE `Time` >= '2013-01-01'
ORDER BY SerialNumber, ID
) AfterSub
INNER JOIN
(
SELECT ID, SerialNumber, Remain_Toner_Black, `Time`, @Counter2:=@Counter2+1 AS SeqCnt
FROM TableName
CROSS JOIN (SELECT @Counter2:=1) Sub2
WHERE `Time` BETWEEN '2013-01-31' AND '2013-01-31'
ORDER BY SerialNumber, ID
) BeforeSub
ON BeforeSub.SerialNumber = AfterSub.SerialNumber
AND BeforeSub.SeqCnt = AfterSub.SeqCnt
AND AfterSub.Remain_Toner_Black > BeforeSub.Remain_Toner_Black
ORDER BY AfterSub.SerialNumber, AfterSub.ID