在 Laravel 中的 GroupBy 之前使用 Orderby

Posted

技术标签:

【中文标题】在 Laravel 中的 GroupBy 之前使用 Orderby【英文标题】:Using Orderby before GroupBy in Laravel 【发布时间】:2020-07-30 14:14:19 【问题描述】:

我有一张表,我想选择以下最低/最低价格的产品名称:

product_name | price 
Cat          |   12
Dog          |   21
Cat          |   14
Dog          |   20
Fish         |   10
Fish         |    3

愿望输出应该是

Cat  | 12
Dog  | 20
Fish | 3

下面是我的 SQL 查询

$products = DB::table('products')
            ->orderBy('products.products_price', 'asc')
            ->groupBy('products.products_name')
            ->get();

当我使用这个脚本时,它只显示最高/最高价格,而不是最低价格

【问题讨论】:

我没有对此进行测试,但应该只是改变排序的方向不能达到你想要的吗? orderBy('products.products_price', 'desc')? 在查询中使用“desc”...看看会发生什么。 我也用过'desc',但它不起作用。 【参考方案1】:

您需要聚合而不是排序。对于 Laravel,这意味着将列与 DB::raw: 一起传递:

$products = DB::table('products')
        ->orderBy('products.products_price', 'asc')
        ->groupBy('products.products_name')
        ->select(['product_name', DB::raw('min(price) as price')])
        ->get();

编辑 ID

在此处取消答案:SQL: Group by minimum value in one field while selecting distinct rows mysql 查询将是

SELECT p1.*     
FROM products p1 INNER JOIN
    (
        SELECT product_name, MIN(price) AS as min_price
        FROM products
        GROUP BY product_name
    ) p2 ON p1.product_name = p2.product_name AND p1.price = p2.min_price

现在我们必须将其转换为查询生成器

$products = DB::table('products AS p1')
   ->join(DB::raw('(
    SELECT product_name, MIN(price) AS as min_price
    FROM products
    GROUP BY product_name
) AS p2'), 
    function($join)
    
       $join->on('p1.product_name', '=', 'p2.product_name');
       $join->on('p1.price', '=', 'p2.min_price');
    )
    ->get(['p1.id', 'p1.product_name', 'p1.price']);

这还没有经过测试,所以我希望它有效

【讨论】:

谢谢,但这并不能显示正确的产品“ID”。即如果 Cat 是 ID 1 和 3。最低/min 的 Cat 是 ID 1。因此输出应该是 Product ID =1 和 Product_name = Cat 和 Price = 12。您建议的 SQL 查询给出了正确的 product_name 但产品 ID 是错误的。即它使用具有最低价格的产品 ID 3,而不是具有最低价格的产品 ID 1 啊,你没有提到产品ID。这增加了一个新的皱纹 很抱歉。当我仔细查看我发现的输出时。请帮忙,我在这上面已经超过 24 小时了 我已经更新了我的答案。我希望它有所帮助。另外值得注意的是,Laravel 现在有 subquery joins 这可能也会有所帮助【参考方案2】:

问题:

您没有定义价格属性应该聚合到最低限度。


解决方案:

如果您想要最高价格,您需要选择 MIN() 聚合。 您可以使用->selectRaw('MIN(price) as max_price') 来执行此操作。


请注意:

如果您还想选择其他属性,只需添加它们以逗号分隔。

->selectRaw('name, MAX(price) as max_price')

@edit

您还在使用 oderBy 吗?如果没有,请尝试使用 orderBy('products.products_price', 'ASC')

【讨论】:

谢谢,但这并不能显示正确的产品“ID”。即如果 Cat 是 ID 1 和 3。具有最低/min 的 Cat 是 ID 1。因此输出应该是 Product ID = 1 和 Product_name = Cat 和 Price = 12。您建议的 SQL 查询给出了正确的 product_name 但产品 ID 是错误的。即它使用具有最低价格的产品 ID 3,而不是具有最低价格的产品 ID 1。 ye id 不正确,但您的问题中没有问到这一点 @LampSoft 看看我的编辑你还用orderBy吗?

以上是关于在 Laravel 中的 GroupBy 之前使用 Orderby的主要内容,如果未能解决你的问题,请参考以下文章

laravel 中的 Groupby 将分组的项目留在对象中

groupby 函数不适用于 laravel 5.5 中的二维数组

如何在关系 Laravel 中使用“groupBy”

如何为 Laravel ORM 中每个组中的单个项目执行 groupBy()

如何在 Laravel 的 hasMany 关系中使用 groupBy

Laravel 8 GroupBy 仅向我返回每个组的第一条记录,但我需要按组中的所有记录