【问题标题】:Laravel Query Builder Join clause is ignoring orderBy()Laravel Query Builder Join 子句忽略 orderBy()
【发布时间】:2021-08-27 19:24:11
【问题描述】:

我正在使用 Laravel 查询生成器,我想问如果返回很多行,如何指定用于左连接的行?

我有这样的代码:

$builder->leftJoin('table2', function (JoinClause $join) {
    $join->on('table2.id', '=', "table1.id")
         ->on('table2.region', '=', "table1.region")
         ->orderBy('table2.updatedAt', 'DESC') // This is being ignored.
         ->limit(1);

});

$join->on()->on() 部分返回多行,因此我需要指定哪一行用于左连接。我虽然可以通过table2.updatedAt 订购它,然后它将使用第一行进行左连接。但它完全忽略了orderBy。所以我不知道如何得到一个特定的行。

编辑: 也有可能来自 table2 的某些行具有完全相同的 table2.updatedAt。在这种情况下,选择具有相同 table2.updatedAt 的哪个并不重要。

【问题讨论】:

    标签: mysql laravel query-builder


    【解决方案1】:

    检查laravel中的查询,我发现应用ORDER BY不会对查询应用任何子句。

    阅读您的要求,您希望在指定的条件下获得具有最大 updatedAt 字段的记录。如果允许,我个人会在视图中选择MAX() 查询,但views 可以被组织限制或不使用,并且很高兴知道如何根据您的问题进行操作,而且这意味着您没有保持一个观点。或者,您可以在子查询中执行MAX(),但这需要更多设置。

    首先,您在需要的字段上进行内部连接。其次,您执行左连接以在该连接中查找大于您想要的 MAX 的值。所以我们想要最新的 updatedAt 字段。最后,你WHERE 最大的 updatedAt 值没有比它更大的值,所以它是真正的最大值:该值是NULL

    代码在没有 leftJoin 子句对象的情况下重新混合,我到处传递你的构建器。我看不到您查询的其余部分,但我认为这应该直接插入,因为最多只有 2 个表,即 table2。如果您在 WHERE 子句中提供 1 个 table.id,您将返回 1 行。

    更新:您需要对 ID 执行相同操作,因此如果您有 2 个具有相同时间戳的日期时间,则选择 ID 较高的一个:

        $sql->join('table2', function ($sql) {
            $sql->on('table2.id', '=', "table1.id")
                ->on('table2.region', '=', "table1.region");
        });
    
        $builder->leftJoin('table2 AS biggerThanUpdatedAt', function ($builder) {
            $builder->on('table2.id', '=', "biggerThanUpdatedAt.id")
                ->on('table2.region', '=', "biggerThanUpdatedAt.region")
                ->on('table2.updatedAt', '<', 'biggerThanUpdatedAt.updatedAt');
        });
    
        $builder->leftJoin('table2 AS biggerThanId', function ($builder) {
            $builder->on('table2.id', '<', "biggerThanId.id") //<-notice the greater at is here this time.
                ->on('table2.region', '=', "biggerThanId.region")
                ->on('table2.updatedAt', '=', 'biggerThanId.updatedAt');
        });
    
        $builder->whereNull('biggerThanUpdatedAt.updatedAt');
        $builder->whereNull('biggerThanId.id');
    

    【讨论】:

    • 这是一个非常有创意的解决方案,谢谢!但是我应该在问题中提到它。很可能 table2 中的某些行具有完全相同的 updatedAt 所以如果我正确实施它仍然可能不是一行而是两行,对吗?坦率地说,我只有在测试溶液时才发现这一点。我编辑了问题以包含它。有没有办法克服这个问题?
    • 你说的很对,我以为我在写答案的时候忘记了什么。如果像时间这样的价值是独一无二的,这通常会让你走出困境。我会写一个更新。
    • 好的,更新完毕。自从我用这种风格编写查询以来已经有一段时间了,因为在这个级别我会选择 View 给定 mysql 的约束,但如果内存服务应该是正确的。
    猜你喜欢
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    • 2019-10-31
    • 2016-04-10
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多