只要前面的记录值较低,就选择一条记录

时间:2013-09-14 11:29:55

标签: mysql sql

我使用mysql,我从来没有遇到过这么大的挑战。 我希望你能帮忙..

我有一个名为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的记录,并使用相同的SerialNumber(之前的意思是较低的ID,具有相同的SerialNumber)。

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

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

2 个答案:

答案 0 :(得分: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()SerialNumber按升序排列的每个ID的其他RDBS上模仿SerialNumber

然后通过生成{{1}}和序列号来连接两个子查询。在生成的数字上,第一个子查询上的值必须等于第二个子查询上的值的一个,以获得下一个reord上的碳粉数量。

答案 1 :(得分: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是从您的评论到另一个答案)

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