marcha/laravel-cte
支持 Laravel 查询中的常见表表达式 (CTE)
资助包维护!
paypal.me/JonasStaudenmeir
Requires
- php: ^8.2
- illuminate/database: ^11.0
Requires (Dev)
- harrygulliford/laravel-firebird: dev-laravel-11.x
- larastan/larastan: ^2.9
- orchestra/testbench: ^9.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^11.0
- singlestoredb/singlestoredb-laravel: ^1.5.4
- yajra/laravel-oci8: ^11.2.4
README
此 Laravel 扩展为查询构建器和 Eloquent 添加了对常见表表达式 (CTE) 的支持。
支持 Laravel 5.5+。
兼容性
- MySQL 8.0+
- MariaDB 10.2+
- PostgreSQL 9.4+
- SQLite 3.8.3+
- SQL Server 2008+
- Oracle 9.2+
- SingleStore 8.1+
- Firebird
安装
composer require marcha/laravel-cte:"^1.0"
如果你在 Windows 的 PowerShell 中(例如在 VS Code 中),请使用此命令
composer require marcha/laravel-cte:"^^^^1.0"
版本
用法
SELECT 查询
使用 withExpression()
并提供一个查询构建器实例、一个 SQL 字符串或一个闭包
$posts = DB::table('p') ->select('p.*', 'u.name') ->withExpression('p', DB::table('posts')) ->withExpression('u', function ($query) { $query->from('users'); }) ->join('u', 'u.id', '=', 'p.user_id') ->get();
递归表达式
使用 withRecursiveExpression()
用于递归表达式
$query = DB::table('users') ->whereNull('parent_id') ->unionAll( DB::table('users') ->select('users.*') ->join('tree', 'tree.id', '=', 'users.parent_id') ); $tree = DB::table('tree') ->withRecursiveExpression('tree', $query) ->get();
材料化表达式
使用 withMaterializedExpression()
/withNonMaterializedExpression()
用于(非)材料化表达式(PostgreSQL、SQLite)
$posts = DB::table('p') ->select('p.*', 'u.name') ->withMaterializedExpression('p', DB::table('posts')) ->withNonMaterializedExpression('u', function ($query) { $query->from('users'); }) ->join('u', 'u.id', '=', 'p.user_id') ->get();
自定义列
您可以将表达式列作为第三个参数提供
$query = 'select 1 union all select number + 1 from numbers where number < 10'; $numbers = DB::table('numbers') ->withRecursiveExpression('numbers', $query, ['number']) ->get();
循环检测
MariaDB 10.5.2+ 和 PostgreSQL 14+ 支持原生循环检测以防止递归表达式中的无限循环。将表示循环的列作为第三个参数提供给 withRecursiveExpressionAndCycleDetection()
$query = DB::table('users') ->whereNull('parent_id') ->unionAll( DB::table('users') ->select('users.*') ->join('tree', 'tree.id', '=', 'users.parent_id') ); $tree = DB::table('tree') ->withRecursiveExpressionAndCycleDetection('tree', $query, 'id') ->get();
在 PostgreSQL 中,您可以自定义显示是否检测到循环的列名和跟踪路径的列名
$tree = DB::table('tree') ->withRecursiveExpressionAndCycleDetection('tree', $query, 'id', 'is_cycle', 'path') ->get();
INSERT/UPDATE/DELETE 查询
您可以在 INSERT
、UPDATE
和 DELETE
查询中使用常见表表达式
DB::table('profiles') ->withExpression('u', DB::table('users')->select('id', 'name')) ->insertUsing(['user_id', 'name'], DB::table('u'));
DB::table('profiles') ->withExpression('u', DB::table('users')) ->join('u', 'u.id', '=', 'profiles.user_id') ->update(['profiles.name' => DB::raw('u.name')]);
DB::table('profiles') ->withExpression('u', DB::table('users')->where('active', false)) ->whereIn('user_id', DB::table('u')->select('id')) ->delete();
Eloquent
您可以在 Eloquent 查询中使用常见表表达式
在 Laravel 5.5–5.7 中,此功能需要 QueriesExpressions
特性
class User extends Model { use \Marcha\LaravelCte\Eloquent\QueriesExpressions; } $query = User::whereNull('parent_id') ->unionAll( User::select('users.*') ->join('tree', 'tree.id', '=', 'users.parent_id') ); $tree = User::from('tree') ->withRecursiveExpression('tree', $query) ->get();
递归关系
如果您想实现递归关系,可以使用此包:[staudenmeir/laravel-adjacency-list](https://github.com/staudenmeir/laravel-adjacency-list)
Lumen
如果您正在使用 Lumen,您必须手动实例化查询构建器
$builder = new \Marcha\LaravelCte\Query\Builder(app('db')->connection()); $result = $builder->from(...)->withExpression(...)->get();
在 Eloquent 中,所有版本的 Lumen 都需要 QueriesExpressions
特性。
贡献
请参阅 CONTRIBUTING 和 CODE OF CONDUCT 以获取详细信息。