Lamp Soft
Lamp Soft

Reputation: 53

Using Orderby before GroupBy in Laravel

I have a table that I want to select product_name with lowest/min price the following:

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

THE DESIRE Output should be

Cat  | 12
Dog  | 20
Fish | 3

BELOW IS MY SQL QUERY

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

When I used this script, it only shows the highest/max price, not the lowest price

Upvotes: 1

Views: 280

Answers (2)

Aless55
Aless55

Reputation: 2709

Problem:

You are not defining that the price attribute should be aggregated to a minimum.


Solution:

If you want the max price you need to select the MIN() aggregation. You can do this by using ->selectRaw('MIN(price) as max_price').


Please Note:

If you want other attributes also selected simply add them comma separated.

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

@edit

Do you still use the oderBy? If not, try it with orderBy('products.products_price', 'ASC')

Upvotes: 0

aynber
aynber

Reputation: 23011

You need an aggregate instead of ordering. For Laravel, that means passing in the columns along with a 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();

Edit for ID

Taking off the answer here : SQL: Group by minimum value in one field while selecting distinct rows the mysql query would be

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

Now we have to convert it to Query Builder

$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']);

This has not been tested, so I hope it works

Upvotes: 1

Related Questions