-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpr_finder.rb
More file actions
99 lines (96 loc) · 3.62 KB
/
pr_finder.rb
File metadata and controls
99 lines (96 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class PrFinder
attr_reader :workouts
def initialize(workouts)
@workouts = workouts
end
def self.update
modified_rows = ActiveRecord::Base.connection.execute <<-SQL
with exercise_groups as (
select
exercises.id as exercise_id,
coalesce(exercises.synonym_of_id, exercises.id) as main_exercise_id
from exercises
),
max_weights_in_workout as (
select max(weight_lbs) as weight_lbs,
workout_id,
reps,
exercise_id,
user_id
from exercise_sets
group by workout_id, reps, exercise_id, user_id
),
rep_maxes_in_workout as (
select
exercise_sets.weight_lbs,
max(id) as exercise_set_id,
exercise_sets.workout_id,
exercise_sets.reps,
exercise_groups.main_exercise_id as exercise_id,
exercise_sets.user_id
from exercise_sets
join max_weights_in_workout on
exercise_sets.workout_id = max_weights_in_workout.workout_id AND
exercise_sets.reps = max_weights_in_workout.reps AND
exercise_sets.exercise_id = max_weights_in_workout.exercise_id AND
exercise_sets.user_id = max_weights_in_workout.user_id AND
exercise_sets.weight_lbs = max_weights_in_workout.weight_lbs
join exercise_groups on exercise_groups.exercise_id = exercise_sets.exercise_id
group by
exercise_sets.weight_lbs,
exercise_sets.workout_id,
exercise_sets.reps,
exercise_groups.main_exercise_id,
exercise_sets.user_id
),
maxes_by_date as (
select
weight_lbs,
workouts.date as date,
reps,
rep_maxes_in_workout.exercise_id as exercise_id,
rep_maxes_in_workout.exercise_set_id as exercise_set_id,
rep_maxes_in_workout.user_id as user_id,
max(weight_lbs) over (partition by rep_maxes_in_workout.user_id, exercise_id, reps order by date) max_to_date
from rep_maxes_in_workout
join workouts on workout_id = workouts.id
where weight_lbs is not null
and reps > 0
),
maxes_with_previous_max as (
select maxes_by_date.*,
lag(max_to_date) over (partition by user_id, exercise_id, reps order by date) prev_max_weight
from maxes_by_date
),
ranked_maxes as (
select *,
row_number() over (partition by user_id, exercise_id, reps order by weight_lbs desc)
from maxes_with_previous_max
where (max_to_date > prev_max_weight or prev_max_weight is null)
),
sets_for_update as (
select
exercise_sets.id as exercise_set_id,
ranked_maxes.exercise_set_id is not null as pr,
ranked_maxes.exercise_set_id is not null and row_number = 1 as latest_pr
from exercise_sets
left join ranked_maxes on ranked_maxes.exercise_set_id = exercise_sets.id
where
(ranked_maxes.exercise_set_id is not null and
(exercise_sets.pr = false
or (exercise_sets.latest_pr = true and row_number > 1))
or (exercise_sets.latest_pr = false and row_number = 1))
or
(ranked_maxes.exercise_set_id is null and exercise_sets.pr = true)
)
update exercise_sets
set pr = sets_for_update.pr,
latest_pr = sets_for_update.latest_pr,
updated_at = now()
from sets_for_update
where exercise_sets.id = sets_for_update.exercise_set_id
returning exercise_sets.workout_id
SQL
return modified_rows.map{ |r| r["workout_id"]}.uniq
end
end