【问题标题】:Using Orderby before GroupBy in Laravel在 Laravel 中的 GroupBy 之前使用 Orderby
【发布时间】: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',但它不起作用。

标签: php sql laravel eloquent


【解决方案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吗?
猜你喜欢
  • 2016-01-22
  • 1970-01-01
  • 2015-02-01
  • 2016-12-27
  • 2018-07-06
  • 2014-10-21
  • 2023-02-05
  • 2018-10-23
  • 2016-01-21
相关资源
最近更新 更多