从两行获取每个值的差异

时间:2018-03-24 07:45:56

标签: php mysql sql laravel laravel-5

所以我有query这个组company,并从salesreport

中查找每个公司的最新两行
App\salesreport::join(DB::RAW('(SELECT company_id, GROUP_CONCAT(periods ORDER BY periods DESC) grouped_periods FROM salesreport GROUP BY company_id ) latest_report'),function($join){
        $join->on('salesreport.company_id','=','latest_report.company_id');
        $join->whereBetween(DB::raw('FIND_IN_SET(`salesreport`.`periods`, `latest_report`.`grouped_periods`)'), [1, 2]);
    })->get();

及其返回的表格如下所示

+----+------------+-------+------------+
| id | company_id | value |  periods   |
+----+------------+-------+------------+
|  1 | A1         |   100 | 2017-02-02 |  
|  2 | A1         |   150 | 2017-01-01 |  
|  3 | A2         |    80 | 2017-06-01 |  
|  4 | A2         |    60 | 2017-04-01 | 
+----+------------+-------+------------+

并且为了下一步,我想找到每个值的差异(在这个简单的例子中只是值列,但真正的项目包含很多列

使它像这个表

+----+------------+-----------+------------+
| id | company_id |   value   |  periods   |
+----+------------+-----------+------------+
|  1 | A1         | 100 (-50) | 2017-02-02 |
|  3 | A2         | 80 (+20)  | 2017-06-01 |
+----+------------+-----------+------------+

怎么做?是否可以在一个数据库请求中?因为我认为我们已经掌握了数据,但需要找到一种优雅的方法来为销售报告中的每个公司组在第一行和第二行之间进行计算,并将其转换为一些新的字段

所以也许像是

App\salesreport::join(DB::RAW('(SELECT company_id, GROUP_CONCAT(periods ORDER BY periods DESC) grouped_periods FROM salesreport GROUP BY company_id ) latest_report'),function($join){
        $join->on('salesreport.company_id','=','latest_report.company_id');
        $join->whereBetween(DB::raw('FIND_IN_SET(`salesreport`.`periods`, `latest_report`.`grouped_periods`)'), [1, 2]);
    })->addSelect([DB::raw('(row1.value - row2.value) as row_differences')])->get();

1 个答案:

答案 0 :(得分:0)

这是可能的(但可能不是一个好主意):

App\salesreport::join(DB::RAW('(SELECT company_id, MAX(periods) AS max_periods FROM salesreport GROUP BY company_id ) latest_report'),function($join){
    $join->on('salesreport.company_id','=','latest_report.company_id');
    $join->on('salesreport.periods','=','latest_report.max_periods');
})->select('*')->selectRaw(
    'CAST(`value` AS SIGNED)-CAST((
        SELECT `value`
        FROM `salesreport`
        WHERE `company_id`=`latest_report`.`company_id`
        ORDER BY `periods` DESC
        LIMIT 1,1
    ) AS SIGNED) as `difference`'
)->get();

如果value列为SIGNED,则可以移除广告。