4

我使用 mysql,我从未遇到过如此巨大的挑战。我希望你能帮助..

我有 1 个名为 Reports 的表:

ID         SerialNumber         Remain_Toner_Black   
7099       Z5UEBJAC900002Y      37   
7281       Z5UEBJAC900002Y      36  
7331       Z5UEBJAC900002Y      100  
7627       8Z37B1DQ100105N      58  
7660       8Z37B1DQ100105N      57  
5996       CND8DDM2FH           83 
5971       CND8DDM2FH           83 
7062       3960125290           0 
7088       3960125290           93 
7100       3960125290           100 

现在我希望能够从表中选择 Remain_Toner_Black 高于表中具有相同序列号的前一行的 Remain_Toner_Black 的记录(之前我的意思是具有相同序列号的较低 ID)。

对于上述记录,我想要以下结果:

ID         SerialNumber        Remain_Toner_Black_Before    Remain_Toner_Black_After
7331       Z5UEBJAC900002Y     36                           100
7088       3960125290          0                            93
7100       3960125290          93                           100
4

2 回答 2

4
SELECT  a.ID, a.SerialNumber, 
        b.Remain_Toner_Black BeforeCount,
        a.Remain_Toner_Black AfterCount
FROM    
        (
            SELECT  A.ID, 
                    A.SerialNumber, 
                    A.Remain_Toner_Black,
                    (
                        SELECT  COUNT(*)
                        FROM    tableName c
                        WHERE   c.SerialNumber = a.SerialNumber AND
                                c.ID <= a.ID) AS RowNumber
            FROM    TableName a
        ) a
        INNER JOIN
        (
            SELECT  A.ID, 
                    A.SerialNumber, 
                    A.Remain_Toner_Black,
                    (
                        SELECT  COUNT(*)
                        FROM    tableName c
                        WHERE   c.SerialNumber = a.SerialNumber AND
                                c.ID <= a.ID) AS RowNumber
            FROM    TableName a
        ) b ON a.SerialNumber = b.SerialNumber AND
                a.RowNumber = b.RowNumber + 1
WHERE   b.Remain_Toner_Black < a.Remain_Toner_Black

输出

╔══════╦═════════════════╦═════════════╦════════════╗
║  ID  ║  SERIALNUMBER   ║ BEFORECOUNT ║ AFTERCOUNT ║
╠══════╬═════════════════╬═════════════╬════════════╣
║ 7331 ║ Z5UEBJAC900002Y ║          36 ║        100 ║
║ 7088 ║ 3960125290      ║           0 ║         93 ║
║ 7100 ║ 3960125290      ║          93 ║        100 ║
╚══════╩═════════════════╩═════════════╩════════════╝

简要说明

上面的查询所做的是它生成一个序列号,该序列号ROW_NUMBER()在其他 RDBS 上模拟每个按升序SerialNumber排序的 by 。ID

然后通过SerialNumber生成的和序列号连接这两个子查询。在生成的数字上,第一个子查询上的值必须等于第二个子查询上的值加上一个,才能获得下一次重新排序的碳粉数量。

于 2013-09-14T11:40:14.897 回答
1

MySQL(或实际上大多数其他 RDBMS)不容易允许跨行比较。

要执行这种查询,您必须执行非常昂贵的连接,将一个版本的表与另一个版本的表的几行进行比较,或者使用用户变量构造一个复杂的表达式。

例如(使用用户变量):

SELECT ID, SerialNumber, @x Remain_Toner_Before, 
        @x := Remain_Toner_Black AS Remain_Toner_After
FROM Reports, (SELECT @x := -4) x
WHERE Remain_Toner_Black > @x 
  AND SerialNumber = '3960125290'
ORDER BY ID;

(这-4是从您的评论到另一个答案)

更好的解决方案是使用游标或在您的应用程序代码中执行此操作,您只需执行一次并通过在游标或应用程序代码中使用变量来比较简单的逻辑。

于 2013-09-14T11:50:19.750 回答