0

I'm trying to create a Rails Postgres query which reuses variables.

A video has many activities(think statistics). Each activity records a video watched and the progress of the video viewed(0-100)%

To generate a video report table which can be paginated I need to query to get all video watching activities and for each video get a) how many views total b) how many views had a progress(integer) that was greater or equal to 90% c) compute the percentage of those who viewed more than 90% e.g. (b/a)*100

The below code is roughly how it should work ( a combination of real and sudo code)

  Video.joins(:activities)
       .where('occurred_at >= ? AND occurred_at <= ?', @start_time, @end_time)
       .select('videos.*, COUNT(activities.id) as total_views, COUNT(activities.progress >= 90) as completed_views, case when total_views = 0 then 0.0 else ROUND( 100.0 *(completion_views/ cast(total_views as float)) ) end as percent_completed')
       .group('videos.id')
       .page(@page).per(@per_page)

How can I reuse the variables total_views and completed_views in the select query to create the percent_completed variable and make they query work. I also realise the calculation COUNT(activities.progress >= 90) as completed_views is not correct either and I'm not sure how to do this.

1 Answer 1

1

You need to use the above query in a subquery.

subquery = Video.joins(:activities)
     .where('occurred_at >= ? AND occurred_at <= ?', @start_time, @end_time)
     .select('videos.*, COUNT(activities.id) as total_views, COUNT(activities.progress >= 90) as completed_views')
     .group('videos.id').as('videos')

Video
  .select('videos.*, case when total_views = 0 then 0.0 else ROUND( 100.0 *(completion_views/ cast(total_views as float)) ) end as percent_completed')
  .from(subquery).page(@page).per(@per_page)

(I'm just using the pseudocode that you provided above, but the general idea is solid.)

Sign up to request clarification or add additional context in comments.

1 Comment

This worked - Thanks. Note: I had to rewrite the joins query method in the subquery as Rails uses $1 in the query which results in the error PG::ProtocolViolation: ERROR

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.