Reputation: 433
Is this is a good query in performance or I can somehow optimize this query? I need to select date column from rental_schedules table and count how many available same dates are available (rental_schedule_status = 1):
$reservationTimes = RentalSchedule::distinct()
->select('date',
DB::raw('(SELECT count(date) FROM rental_schedules AS r2
WHERE r2.date = rental_schedules.date and rental_schedule_status = 1) as free_time'))
->where('premises_id', $id)->pluck('free_time', 'date');
Thanks in advance!
Upvotes: 1
Views: 54
Reputation: 5731
You can get result without join or subquery :
Try this :
$reservationTimes = RentalSchedule::select('date',\DB::Raw("sum(case when rental_schedule_status = 1 then 1 else 0 end) as free_time"))
->where('premises_id', $id)
->groupBy('date')
->get()
->pluck('free_time', 'date');
Upvotes: 1
Reputation: 521914
You could try to phrase your query using left join to a subquery, e.g.
SELECT
rs1.date,
COALESCE(rs2.cnt, 0) AS free_time
FROM rental_schedules rs1
LEFT JOIN
(
SELECT date, COUNT(*) AS cnt
FROM rental_schedules
WHERE rental_schedule_status = 1
GROUP BY date
) rs2
ON rs1.date = rs2.date
WHERE
rs1.premises_id = ?;
Your updated Laravel code:
$reservationTimes = RentalSchedule:from("RentalSchedule AS rs1")
->select(DB::raw('rs1.date, COALESCE(rs2.cnt, 0) AS free_time'))
->join(DB::raw('(SELECT date, COUNT(*) AS cnt
FROM rental_schedules
WHERE rental_schedules_status = 1
GROUP BY date) rs2'),
function($join) {
$join->on('rs1.date', '=', 'rs2.date');
})
->where('premises_id', $id)
->pluck('free_time', 'date');
You may also try adding an index on (rental_schedules_status, date)
, to speed up the subquery:
CREATE INDEX idx ON rental_schedules (rental_schedules_status, date)
Upvotes: 1