In a project, I'm using a Common Table Expression (CTE) in Postgres for a recursive expression on a table. The recursive expression figures out all child rows under a parent.
I'm using the Laravel framework with query builder to write this query. I would like to avoid raw queries. I am looking for a way to chain the CTE in the query builder syntax, but I end up with a raw query (DB::select('raw query here'))
.
Is there a way that I can chain the CTE part? Like below in pseudo code:
DB::statement('WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
UNION ALL
SELECT p.sub_part, p.part, p.quantity
FROM included_parts pr, parts p
WHERE p.part = pr.sub_part')
->select('subpart')
->table('included_parts')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->etc etc more query expressions
The CTE query starts with a “With” and is followed by the Expression Name. We will be using this expression name in our select query to display the result of our CTE Query and be writing our CTE query definition. To view the CTE result we use a Select query with the CTE expression name.
By using the variable materialize_ctes , common table expressions (CTEs) are materialized when queries with CTEs are run. The materialized results can then be referenced multiple times by the parent query. The CTE queries are cached, which results in optimized performance.
I've created a package for common table expressions: https://github.com/staudenmeir/laravel-cte
$query = 'SELECT sub_part, part, quantity FROM parts [...]';
DB::table('included_parts')
->withRecursiveExpression('included_parts', $query, ['sub_part', 'part', 'quantity'])
->select('subpart')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->[...]
You can also provide a query builder instance:
$query = DB::table('parts')
->where('part', 'our_product')
->unionAll(
DB::query()->[...]
)
DB::table('included_parts')
->withRecursiveExpression('included_parts', $query, ['sub_part', 'part', 'quantity'])
->select('subpart')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->[...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With