I am trying to convert this SQL query to Eloquent in Laravel
Convert SQL code to Eloquent
SELECT
session_id,
SUM(points) AS total_points
FROM
(
SELECT
session_id,
spent_points AS points
FROM
session_details
WHERE
session_id IN
(
" - Meagevy6y9ukbmFXvB7",
" - Meak6dG9iqvHWfAGQvy"
)
UNION ALL
SELECT
session_id,
price_points
FROM
template_sales
WHERE
session_id IN
(
" - Meagevy6y9ukbmFXvB7",
" - Meak6dG9iqvHWfAGQvy"
)
)
t
GROUP BY
session_id
my code in Laravel but not working
$ids = ["-Meagevy6y9ukbmFXvB7","-Meak6dG9iqvHWfAGQvy"];
$query = DB::table('session_details')
->select('session_id',DB::raw('SUM(points) AS total_points FROM ( SELECT session_id, spent_points AS points FROM session_details
WHERE session_id IN ("'.$ids.'") UNION ALL SELECT session_id,price_points FROM template_sales WHERE session_id IN ("'.$ids.'") ) t GROUP BY session_id'))
->get();
I'd advise you to use Eloquent models & Eloquent relationships to make the query more readable.
Execute the following in your terminal to create a new model:
php artisan make:model SessionDetail
Open the file that Laravel has generated for you in /app/Models (or whatever folders your models are in), and set the table in the model by putting the following property into the model class: public $table = "session_details";
If your model does not use or have Laravel timestamps which are usually created_at & updated_at, you can also use this property to disable them in the model: public $timestamps = false;
After that, create generate another model by execute the following command in your terminal:
php artisan make:model TemplateSale
Follow the same instructions again but this time change the table name to template_sales
After you have done that, head into your SessionDetail model and make a relationship to the TemplateSale model using the following code (this must be in the model class beneath the properties):
public function template_sales() {
return $this->hasMany(TemplateSale::class);
}
After that, you can replace your query with this line of code:
$query = \App\Models\SessionDetail::select("session_id", "SUM(points) as total_points")->whereIn("session_id", $ids)->get();
To get the template sales from that query, you have to use $query->template_sales;
If I got anything wrong, please tell me & I'll fix it ASAP
There is documentation available for all the operations in your query.
select('column1', 'column2', ...)selectRaw('sum(column) as column')WHERE column IN (...) use whereIn('column', $array)Closures or Builder classes (DB::table(fn($q) => ... , alias) or DB::table($builder, alias))UNION ALL use unionAll() with the same syntax as subquery tables.$ids = ["-Meagevy6y9ukbmFXvB7","-Meak6dG9iqvHWfAGQvy"];
$query = DB::table(function ($sub) use ($ids) {
$sub->select('session_id', 'spent_points as points')
->from('session_details')
->whereIn('session_id', [1,2])
->unionAll(function ($union) use ($ids) {
$union->select('session_id', 'price_points')
->from('template_sales')
->whereIn('session_id', $ids);
});
}), 't')
->select('session_id')
->selectRaw('sum(points) as total_points')
->groupBy('session_id')
->get();
$ids = ["-Meagevy6y9ukbmFXvB7","-Meak6dG9iqvHWfAGQvy"];
$union = DB::table('template_sales')
->select('session_id', 'price_points')
->whereIn('session_id', $ids);
$sub = DB::table('session_details')
->select('session_id', 'spent_points as points')
->whereIn('session_id', $ids)
->unionAll($union);
$query = DB::table($sub, 't')
->select('session_id')
->selectRaw('sum(points) as total_points')
->groupBy('session_id')
->get();
Pick whichever you prefer. Both evaluate to the same query you posted.