MySQL:获取前一行

时间:2015-02-11 11:55:37

标签: mysql

我有以下查询:

SELECT c.called as customer, c.calling as company, DATE_FORMAT(c.`end`,'%Y-%m-%d') as _date,

       @G := if(@prevComp <> c.calling AND @prevCust = c.called AND @prevDay = DATE_FORMAT(c.`end`,'%Y-%m-%d'), 1, 0) as Gain,
       @prevComp := c.called as prevComp,
       @prevCust := c.calling as prevCust, 
       @prevDay := DATE_FORMAT(c.`end`,'%Y-%m-%d') as prevDate

FROM cdrdata_archive c, 
     (SELECT @prevComp := 0, @prevCust := 0, @prevDay := 0) prevVals
ORDER BY c.called, DATE_FORMAT(c.`end`,'%Y-%m-%d')

但是,这会为prevCustprevCompanyprevDate输出相同的行值:

Customer      Company      Date        prevCust   prevComp   prevDate

00140443360  08434599117  2014-01-28  00140443360  08434599117  2014-01-28
00475172558  08434599218  2014-01-27  00475172558  08434599218  2014-01-27
00475172558  08434599118  2014-01-27  00475172558  08434599118  2014-01-27

所需的输出应为:

Customer      Company      Date        prevCust   prevComp   prevDate

00140443360  08834599117  2014-01-28     null          null        null 
00475172558  08834599218  2014-01-27  00140443360  08834599117  2014-01-28
00475136333  08834098771  2014-01-22  00475172558  08834599218  2014-01-27

1 个答案:

答案 0 :(得分:2)

这很棘手,因为您无法在一个语句中分配变量拉取前一个值。因此,诀窍是使用另一个变量来保存值。

以下逻辑使用case语句和可怕的= NULL获取前一天。我使用它是因为我知道它永远不会是真的,所以case语句simple用作排序变量评估的方法。

您的示例输出没有gain,所以我省略了它:

SELECT c.called as customer, c.calling as company,
       DATE_FORMAT(c.`end`,'%Y-%m-%d') as _date,
       (case when (@t1 := @prevComp) = NULL then @prevComp      -- never happens
             when (@prevComp := c.called) = NULL then @prevComp -- never happens 
             else @t1
        end) as prevComp,
       (case when (@t2 := @prevCust) = NULL then @prevCust       -- never happens
             when (@prevCust := c.calling) = NULL then @prevCust -- never happens 
             else @t2
        end) as prevCust,
       (case when (@t3 := @prevDate) = NULL then @prevDate       -- never happens
             when (@prevCust := c.`end`) = NULL then @prevDate   -- never happens 
             else DATE_FORMAT(@t3,'%Y-%m-%d')
        end) as prevCust
FROM cdrdata_archive c CROSS JOIN
     (SELECT @prevComp := NULL, @prevCust := NULL, @prevDay := NULL) prevVals
ORDER BY c.called, DATE_FORMAT(c.`end`,'%Y-%m-%d');