I have to add a filter condition for fetching a list of reviews with an andWhere()
. Here is the PostgreSQL version:
SELECT *
FROM listing_review
WHERE(
(
edited_rating_meals_nutrition +
edited_rating_treatment_effectiveness +
rating_accommodations_amenities
)
/
(
COALESCE(
NULLIF(
(
(edited_rating_meals_nutrition::BOOLEAN)::INTEGER +
(edited_rating_effectiveness::BOOLEAN)::INTEGER +
(rating_accommodations_amenities::BOOLEAN)::INTEGER
)
, 0
), 1
)
)
)
>= 3;
Basically, I need to average three ratings per row (review) and filter based on whether the average of them is equal to or greater to some integer (5 in this example). If they haven't been reviewed in either category, that category's value is zero, and I have to discard them from the average calculation (hence the double casting from boolean to an integer to get the number of ratings that are not zero). I also can't divide by zero, explaining the COALESCE
.
I'm able to accomplish this the naive way just dividing by three like this:
if (isset($searchParams[self::PARAM_MINIMUM_RATING])) {
$qb
->andWhere('((r.editedRatingTreatmentEffectiveness + r.editedRatingAccommodationsAmenities + r.editedRatingMealsNutrition) / 3) >= :minimum_rating')
->setParameter('minimum_rating', $searchParams[self::PARAM_MINIMUM_RATING]);
How can I do this in DQL making the divisor dynamic (like my PostgreSQL query) instead of hardcoded to 3?