Php 如何在laravel中使子查询具有说服力?

Php 如何在laravel中使子查询具有说服力?,php,laravel,laravel-5.3,laravel-eloquent,Php,Laravel,Laravel 5.3,Laravel Eloquent,当我使用db raw时,它可以工作 我的查询使用db raw,如下所示: $products = DB::select(DB::raw('SELECT * FROM ( SELECT a.*, b.name AS store_name, b.address FROM products a JOIN stores b ON b.id = a.st

当我使用db raw时,它可以工作

我的查询使用db raw,如下所示:

$products = DB::select(DB::raw('SELECT * 
                FROM (
                    SELECT a.*, b.name AS store_name, b.address
                    FROM products a
                    JOIN stores b ON b.id = a.store_id
                    WHERE a.category_id = '.$category_id.'
                    ORDER BY a.total_sold DESC, a.updated_at DESC
                    LIMIT '.$num.'
                ) AS product
                GROUP BY store_id'));
$products = Product::where('category_id', '=', $category_id)
     ->with('store')
     ->groupBy('store_id')
     ->orderBy('total_sold','desc')
     ->orderBy('updated_at', 'desc')
     ->take($num)
     ->get();
它起作用了。但我想改变它,用拉威尔的口才

我试着这样:

$products = DB::select(DB::raw('SELECT * 
                FROM (
                    SELECT a.*, b.name AS store_name, b.address
                    FROM products a
                    JOIN stores b ON b.id = a.store_id
                    WHERE a.category_id = '.$category_id.'
                    ORDER BY a.total_sold DESC, a.updated_at DESC
                    LIMIT '.$num.'
                ) AS product
                GROUP BY store_id'));
$products = Product::where('category_id', '=', $category_id)
     ->with('store')
     ->groupBy('store_id')
     ->orderBy('total_sold','desc')
     ->orderBy('updated_at', 'desc')
     ->take($num)
     ->get();
它也起作用。但orderBy在未执行时更新了_


我怎样才能解决它呢?

我觉得您使用的分组方式不正确。即使在我看来这是偶然的之前,您为查询检索到了正确的结果。应使用Group by聚合查询结果并获取聚合列值。如果不正确地使用,选择未实际聚合的列可能会很危险

从5.6版的Mysql文档:

MySQL扩展了GROUPBY的标准SQL用法,因此select列表可以引用GROUPBY子句中未命名的未聚合列。这意味着前面的查询在MySQL中是合法的。您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要是在GROUP BY中未命名的每个未聚合列中的所有值对于每个组都相同时才有用。服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的。此外,添加ORDERBY子句不会影响从每个组中选择值。结果集排序发生在选择值之后,排序依据不影响服务器在每个组中选择的值

此外,从MySql 5.7.5开始,默认的SQL模式仅包括_FULL_GROUP_BY标志,该标志将:

拒绝select list、HAVING CONDICTION或ORDER BY list引用的未聚合列的查询,这些列既不在GROUP BY子句中命名,也不在功能上依赖于GROUP BY列(由GROUP BY列唯一确定)

出于教育目的,您应该能够使用类似这样的Laravel实现完全相同的查询(未经测试且不使用表别名),但我会避免使用它:

$subQuery = Products::selectRaw('products.*, stores.name as store_name, stores.address')
    ->join('stores', 'stores.id', '=', 'products.store_id')
    ->where('products.category_id', '=', $category_id)
    ->orderBy('products.total_sold', 'DESC')
    ->orderBy('products.updated_at', 'DESC')
    ->take($num)

$products = DB::table(DB::raw('(' . $subQuery->toSql() . ') t'))
    ->groupBy('store_id')
    ->setBindings($subQuery->getBindings())
    ->get();
但对我来说,你要做的似乎是把所有的商店和你想要的产品放在一起。因此,最为Laravel的解决方案可能是:

Stores::with(['products' => function($productsQuery) use ($category_id) {
    // This limits all the retrieved products to the provided category
    $productsQuery
        ->where('category_id', '=', $category_id)
        ->orderBy('total_sold', 'DESC')
        ->orderBy('updated_at', 'DESC');
}])->whereHas('products', function($productsQuery) use ($category_id) {
    // This makes sure that the store actually has at least one product from the category
    $productsQuery->where('category_id', '=', $category_id);
})->get();

通过查看您的查询,我可能做出了错误的假设,但目前没有多大意义。。。无论如何,我会从这里开始。

你能把
->toSql()粘贴在上面吗?
让我们知道query@Agam班加,
select*从类别为的产品中?按门店id订单按销售总额分类,根据sql中的描述限值4更新,似乎查询已更新列中的描述限值。你面临什么问题?@Agam Banga,它没有执行。可能是因为
分组。如果我删除
分组依据
,它会工作啊!您似乎错过了
join
with stores表