使用 Eloquent 根据列/属性的最高整数获取结果的最佳方法

问题描述 投票:0回答:1

我面临着必须重构我的模型的问题,以便每个模型能够基于一个刻度存在多个实例。可以有很多刻度,它们从零开始递增,一个接着一个,每个刻度标识一个时间段。我想根据可用的最高刻度获取表上的许多行。因此,搜索第

component
列将返回第
tick
列的最高记录。此外,蜱虫可能尚未发生,因此需要以如下方式检查蜱虫:

$components = $this->where('tick', '<=', $tick)->orderBy('tick', 'DESC')->get();

因此,这可以通过数字选择

tick
之前发生的
all
记录来删除所有未来出现的
$tick

考虑这个数据集。

+----+------+------------+--------+
| id | tick | branch     | amount |
+----+------+------------+--------+
|  1 |    2 | components |    100 |
|  2 |    2 | research   |     50 |
|  3 |    3 | research   |     55 |
|  4 |    4 | research   |     60 |
+----+------+------------+--------+

假设

$tick
为 3,这意味着从
id
1
2
3
中选择了 3 条记录。但我想要的是
id
1
3
的记录,因为
2
已过时,因为它发生在
3
之前。

换句话说,我期望达到低于某个值的最高跳动记录。为了验证该场景,请参阅下文。

+----+------+------------+--------+--------+
| id | tick | branch     | type   | amount |
+----+------+------------+--------+--------+
|  1 |    2 | components | light  |    100 |
|  2 |    2 | components | medium |     90 |
|  3 |    2 | components | heavy  |     80 |
|  4 |    3 | components | light  |    110 |
|  5 |    4 | components | light  |    120 |
|  6 |    2 | research   | waves  |     50 |
|  7 |    3 | research   | waves  |     55 |
|  8 |    4 | research   | waves  |     60 |
+----+------+------------+--------+--------+

有了这个,当

$tick
4
时,你会期望:

  1. 忽略行

    1
    ,因为它具有
    tick
    3
    的未来
    4

  2. 选择行

    2
    3
    作为其唯一的
    medium
    /
    heavy
    components

  3. 选择行

    5
    8
    忽略行
    4
    6
    7

所以发生的事情是选择每个分支和类型的最后一个刻度。我想以下内容就足够了。

$components = $this->where([['branch' => 'components'], ['type' => 'light'], ['tick', '<=', $tick]])->orderBy('tick', 'DESC')->first();

但这似乎相当麻烦,考虑到

branch
type
可能有许多不同的版本。有没有办法要求为匹配
tick
branch
的所有列选择
type
的最后一次出现(或最大值)?

我尝试了各种组合并阅读了在线文档,但似乎找不到适合我需求的组合。我想象

with
具有某种闭包函数。谁能建议最干净/最好的方法?

php laravel eloquent
1个回答
0
投票

在这种情况下,我们可以将表本身连接起来,同时在给定的

$tick
branch
分组中过滤最大
type
,然后返回该集合中的所有不同结果:

ProductTick::from('product_ticks as t1')
        ->join('product_ticks as t2', function ($join) {
            $join->on('t1.branch', '=', 't2.branch')
                ->on('t1.type', '=', 't2.type')
                ->on('t1.tick', '=', DB::raw('(SELECT MAX(tick) FROM product_ticks WHERE branch = t2.branch AND type = t2.type)'));
        })
        ->select('t1.*')
        ->distinct('id')
        ->get();
© www.soinside.com 2019 - 2024. All rights reserved.