2021-09-06 18:54:36
将原始SQL子查询转换为Laravel查询构建器表达式,核心是通过fromSub方法实现嵌套查询的链式构建。以下是具体步骤和代码示例:
1. 分析原始SQL结构原始SQL包含一个子查询作为FROM子句的临时表(inventory),其功能为:
使用Laravel查询构建器逐步实现子查询逻辑:
use IlluminateSupportFacadesDB;$stores = [1, 2, 3]; // 示例商店ID数组$limit = 0; // 示例偏移量$pageSize = 10; // 示例每页数量$nestedQuery = DB::table('stationary_orders AS o') ->select([ 'i.id AS ItemID', 'o.id AS OrderID', 'o.EmployeeID', 'o.created_date', DB::raw('(o.Quantity * i.price) AS calculation') // 计算字段 ]) ->leftJoin('stationary_items AS i', 'o.Stationary_ID', '=', 'i.id') ->whereIn('o.Store', $stores) // 安全处理IN条件 ->orderBy('o.id', 'DESC') ->offset($limit) ->limit($pageSize);关键点:
通过fromSub将子查询作为临时表,并完成外部查询:
$result = DB::query() ->fromSub($nestedQuery, 'inventory') // 子查询别名 ->select([ 'inventory.EmployeeID', 'inventory.created_date AS OrderDate', DB::raw('SUM(inventory.calculation) AS TotalPrice') // 聚合函数 ]) ->groupBy('inventory.EmployeeID') ->get(); // 返回结果集关键点:
将上述逻辑整合到控制器方法中:
namespace AppHttpControllers;use IlluminateHttpRequest;use IlluminateSupportFacadesDB;class OrderController extends Controller{ public function getEmployeeOrderSummary(Request $request) { // 从请求获取参数(带默认值) $stores = $request->input('stores', [1, 2, 3]); $limit = $request->input('offset', 0); $pageSize = $request->input('limit', 10); // 1. 构建子查询 $nestedQuery = DB::table('stationary_orders AS o') ->select([ 'i.id AS ItemID', 'o.id AS OrderID', 'o.EmployeeID', 'o.created_date', DB::raw('(o.Quantity * i.price) AS calculation') ]) ->leftJoin('stationary_items AS i', 'o.Stationary_ID', '=', 'i.id') ->whereIn('o.Store', $stores) ->orderBy('o.id', 'DESC') ->offset($limit) ->limit($pageSize); // 2. 构建主查询 $employeeOrderSummary = DB::query() ->fromSub($nestedQuery, 'inventory') ->select([ 'inventory.EmployeeID', 'inventory.created_date AS OrderDate', DB::raw('SUM(inventory.calculation) AS TotalPrice') ]) ->groupBy('inventory.EmployeeID') ->get(); return response()->json($employeeOrderSummary); }}5. 注意事项与优化建议使用->toSql()查看生成的SQL语句。
使用->dump()(Laravel 8+)打印查询及绑定参数。
为stationary_orders.Store和Stationary_ID字段添加索引。
复杂查询可拆分为多个简单查询或使用缓存。
通过fromSub方法,Laravel查询构建器能够优雅地处理嵌套查询,兼顾安全性(参数绑定)、可读性(链式调用)和跨数据库兼容性。分解问题为子查询和主查询两步构建,可显著降低复杂查询的开发难度。