SQL分组查询每个组的最新时间和上一个时间的某个字段值的差

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL分组查询每个组的最新时间和上一个时间的某个字段值的差相关的知识,希望对你有一定的参考价值。

新全球通大厦1这个组,最新时间的QOE是66,上一个时间是76,都是相隔5分钟,则差是-10.
最后数据库自连接搞定:
SELECT p1.cellname, p1.qoe, p2.qoe, p1.acqtime, p1.qoe - p2.qoe AS q, p2. *
FROM ur_sum_cell_qoe_minute AS p1, ur_sum_cell_qoe_minute AS p2
WHERE p1.cellname = p2.cellname
AND UNIX_TIMESTAMP( p1.acqtime ) - UNIX_TIMESTAMP( p2.acqtime ) =300
AND p1.qoe - p2.qoe <= -10

参考技术A select datediff(mi,最新时间,上一个时间)
--此求出来的为正数,如果需要负数,在前面加上-号,或者将两个时间调换追问

我是要求QOE的差值哦!

追答

你是要什么?你又说都是相隔5分钟,又说要QOE差值,你把你的问题弄清楚到上面来问,你是要的QOE差值还是时间的差值

追问

相邻时间都是间隔5分钟的,所以没必要求时间差

追答

那你取到你应该取得值不就可以计算啦?
关于分组,你可以考虑用row_number()重新排序来判断是属于哪一组

追问

MYSQL不支持row_number()

追答

没有可以考虑用别的方式啊,row_number也只是别人封装的而已
比如,按照group by找出每种组,然后按照组,循环编号

本回答被提问者采纳

Laravel 获取每个组的最新记录

【中文标题】Laravel 获取每个组的最新记录【英文标题】:Laravel get latest record for each group 【发布时间】:2018-11-22 16:28:14 【问题描述】:

我正在尝试将一些原始 SQL 迁移到我模型上的 Eloquent(或查询生成器)范围。我的零件历史表如下所示:

+----+---------+--------+------------+
| id | part_id | status | created_at |
+----+---------+--------+------------+
|  1 |       1 |      1 | ...        |
|  2 |       1 |      2 | ...        |
|  3 |       2 |      1 | ...        |
|  4 |       1 |      2 | ...        |
|  5 |       2 |      2 | ...        |
|  6 |       1 |      3 | ...        |

请注意,同一个 part_id 可以有多个状态相同的条目。

目前我使用以下选择最新状态:

$part = Part::leftjoin( DB::raw("
 (SELECT t1.part_id, ph.status, t1.part_status_at 
  FROM (
    SELECT part_id, max(created_at) part_status_at
    FROM part_histories
    GROUP BY part_id) t1 
  JOIN part_histories ph ON ph.part_id = t1.part_id AND t1.part_status_at = ph.created_at) as t2
  )", 't2.part_id', '=', 'parts.id')->where( ... )

我正在尝试以此为零件模型制作一个范围,到目前为止我有这个:

public function scopeWithLatestStatus($query)

    return $query->join(DB::raw('part_histories ph'), function ($join) 
         $join->on('ph.part_id', '=', 't1.id')->on('t1.part_status_at', '=', 'ph.created_at');
      )
      ->from(DB::raw('(select part_id as id, max(created_at) part_status_at from part_histories GROUP BY part_id) t1'))
      ->select('t1.id', 'ph.part_status', 't1.part_status_at');

这是其中的一部分(但仍然使用一些原始 SQL),我只是想不通其余的

【问题讨论】:

只是出于好奇,为什么?如果原始 SQL 工作正常,那么切换到 ORM 有什么好处?我知道这与问题无关,我只是好奇。 好点,戈登 :-) 主要是因为我正在将其他东西更改为 ORM。事实证明,我决定坚持使用原始 SQL,因为我并没有很好地解释我的问题。 【参考方案1】:

您可以将查询重写为左连接以获得相同的结果

select a.* 
from part_histories a
left join part_histories b on a.part_id = b.part_id 
                            and a.created_at < b.created_at
where b.part_id is null

我猜你可以在你的范围内轻松转换上面的查询,比如

public function scopeWithLatestStatus($query)

    return $query->leftJoin('part_histories as b', function ($join) 
                $join->on('a.part_id', '=', 'b.part_id')
                     ->where('a.created_at', '<', 'b.created_at');
            )
        ->whereNull('b.part_id')
        ->from('part_histories as a')
        ->select('a.*');

Laravel Eloquent select all rows with max created_at

Laravel - Get the last entry of each UID type

Laravel Eloquent group by most recent record

使用上述查询作为has 关系进行编辑,要获取每个部分的最新历史记录,您可以定义hasOne 关系,如

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class Part extends Model

    public function latest_history()
    
        return $this->hasOne(\App\Models\PartHistory::class, 'part_id')
            ->leftJoin('part_histories as p1', function ($join) 
                $join->on('part_histories.part_id', '=', 'p1.part_id')
                    ->whereRaw(DB::raw('part_histories.created_at < p1.created_at'));
            )->whereNull('p1.part_id')
            ->select('part_histories.*');
    

然后要加载具有最新历史记录的部件,您可以将上述定义的映射加载为

$parts = Part::with('latest_history')->get();

您将获得零件列表以及最新历史记录

Array
(
    [0] => Array
        (
            [id] => 1
            [title] => P1
            [latest_history] => Array
                (
                    [id] => 6
                    [created_at] => 2018-06-16 08:25:10
                    [status] =>  1
                    [part_id] => 1
                )

        )
....
)

【讨论】:

谢谢,但我的错,因为我没有把我的问题说得足够清楚——你提供的东西很好用——但我已经有了这个工作,尽管使用了不同的方法。我应该问的是如何更改范围方法以将最新状态附加到任何 ORM 部分查询:Part::withLatestStatus()->get() @rareclass 您想从您的零件模型中加载此数据吗?而不是应用范围 我想应用范围而不是使用属性,以避免在检索部件集合时出现 n+1 问题。 @rareclass 我想如果您可以将此查询定义为hasOne 并进行急切加载,那么就不会有 n+1 的机会。让我知道这是否有意义,然后我会更新我的答案 有趣,我什至不知道你可以通过 haseOne 关系做到这一点

以上是关于SQL分组查询每个组的最新时间和上一个时间的某个字段值的差的主要内容,如果未能解决你的问题,请参考以下文章

查找 sql 查询以获取每个分组的最新关联日期

oracle SQL 取出每个分组的按照日期最新一条记录,同时还显示每个分组某个字段的总和

如何在SQL中返回每个组的增量组编号

SQL 查询根据日期获取最新的 3 次发送,然后对记录进行分组

SQL如何根据一个字段的某个关键词的前面部分分组查询

SQLSERVER 查询分组后获取每组的最新一条数据