从两行中获取每个值的差异

Posted

技术标签:

【中文标题】从两行中获取每个值的差异【英文标题】:Get differences for each value from two row 【发布时间】:2018-09-02 21:14:37 【问题描述】:

所以我有这个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】:

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

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,则可以删除强制转换。

【讨论】:

hmmm 很奇怪,我刚刚得到的差异与手动计算不匹配,我试图在第一期和第二期手动计算值并得到错误的数字 它是否适用于您问题中的示例数据? 你得到什么结果?

以上是关于从两行中获取每个值的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何获取同一列中两行之间的差异

如何从两列之间的差异创建新列?

Oracle - 两个表中两行之间的差异或变化

在 postgres 行中找到最大差异

从 SQLite 中的所有行中减去平均值

从两行获取字符串的正则表达式模式