Skip to content

Commit

Permalink
View for 2025 hardrock lottery ticket calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
moveson committed Dec 1, 2024
1 parent c4da69c commit 54587a0
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class CreateLotteryTicketCalcHardrock2025s < ActiveRecord::Migration[7.0]
def change
create_view :lottery_ticket_calc_hardrock_2025s
end
end
122 changes: 113 additions & 9 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_11_27_064733) do
ActiveRecord::Schema[7.0].define(version: 2024_12_01_163355) do
# These are extensions that must be enabled in order to support this database
enable_extension "fuzzystrmatch"
enable_extension "pg_trgm"
Expand Down Expand Up @@ -843,16 +843,16 @@
LEFT JOIN lottery_draws ON ((lottery_draws.lottery_ticket_id = lottery_tickets.id)))
ORDER BY lottery_entrants.id, lottery_draws.id
)
SELECT entrant_list.lottery_id,
entrant_list.division_id,
entrant_list.division_name,
entrant_list.number_of_tickets,
count(*) FILTER (WHERE entrant_list.accepted) AS accepted_entrants_count,
count(*) FILTER (WHERE entrant_list.waitlisted) AS waitlisted_entrants_count,
SELECT lottery_id,
division_id,
division_name,
number_of_tickets,
count(*) FILTER (WHERE accepted) AS accepted_entrants_count,
count(*) FILTER (WHERE waitlisted) AS waitlisted_entrants_count,
count(*) AS entrants_count
FROM entrant_list
GROUP BY entrant_list.lottery_id, entrant_list.division_id, entrant_list.division_name, entrant_list.number_of_tickets
ORDER BY entrant_list.lottery_id, entrant_list.division_id, entrant_list.division_name, entrant_list.number_of_tickets;
GROUP BY lottery_id, division_id, division_name, number_of_tickets
ORDER BY lottery_id, division_id, division_name, number_of_tickets;
SQL
create_view "course_group_finishers", sql_definition: <<-SQL
SELECT ((cg.id || ':'::text) || p.id) AS id,
Expand All @@ -878,4 +878,108 @@
WHERE ((ef.finished = true) AND (eg.concealed = false))
GROUP BY cg.id, p.id;
SQL
create_view "lottery_ticket_calc_hardrock_2025s", sql_definition: <<-SQL
WITH applicants AS (
SELECT historical_facts.organization_id,
historical_facts.person_id,
any_value(historical_facts.gender) AS gender,
COALESCE(bool_or(((event_groups.organization_id = historical_facts.organization_id) AND (efforts.finished OR (efforts.started AND (EXTRACT(year FROM events.scheduled_start_time) < (2021)::numeric))))), false) AS finisher
FROM (((historical_facts
LEFT JOIN efforts ON ((efforts.person_id = historical_facts.person_id)))
LEFT JOIN events ON ((events.id = efforts.event_id)))
LEFT JOIN event_groups ON ((event_groups.id = events.event_group_id)))
WHERE ((historical_facts.kind = 11) AND (historical_facts.year = 2024))
GROUP BY historical_facts.organization_id, historical_facts.person_id
), last_start_year AS (
SELECT event_groups.organization_id,
efforts.person_id,
max(EXTRACT(year FROM events.scheduled_start_time)) AS year
FROM ((efforts
JOIN events ON ((events.id = efforts.event_id)))
JOIN event_groups ON ((event_groups.id = events.event_group_id)))
WHERE efforts.started
GROUP BY event_groups.organization_id, efforts.person_id
ORDER BY efforts.person_id
), dns_since_last_start_count AS (
SELECT historical_facts.organization_id,
historical_facts.person_id,
count(*) AS dns_since_last_start_count
FROM (historical_facts
LEFT JOIN last_start_year USING (organization_id, person_id))
WHERE ((historical_facts.kind = 0) AND (historical_facts.year < 2025) AND ((historical_facts.year)::numeric > COALESCE(last_start_year.year, (0)::numeric)))
GROUP BY historical_facts.organization_id, historical_facts.person_id
), last_reset_year AS (
SELECT event_groups.organization_id,
efforts.person_id,
max(EXTRACT(year FROM events.scheduled_start_time)) AS year
FROM ((efforts
JOIN events ON ((events.id = efforts.event_id)))
JOIN event_groups ON ((event_groups.id = events.event_group_id)))
WHERE (efforts.finished OR (efforts.started AND (EXTRACT(year FROM events.scheduled_start_time) > (2023)::numeric)))
GROUP BY event_groups.organization_id, efforts.person_id
), dns_since_last_reset_count AS (
SELECT historical_facts.organization_id,
historical_facts.person_id,
count(*) AS dns_since_last_reset_count
FROM (historical_facts
LEFT JOIN last_reset_year USING (organization_id, person_id))
WHERE ((historical_facts.kind = 0) AND (historical_facts.year < 2025) AND ((historical_facts.year)::numeric > COALESCE(last_reset_year.year, (0)::numeric)))
GROUP BY historical_facts.organization_id, historical_facts.person_id
), finish_year_count AS (
SELECT event_groups.organization_id,
efforts.person_id,
count(*) AS finish_year_count
FROM ((efforts
JOIN events ON ((events.id = efforts.event_id)))
JOIN event_groups ON ((event_groups.id = events.event_group_id)))
WHERE (efforts.finished AND (EXTRACT(year FROM events.scheduled_start_time) < (2025)::numeric))
GROUP BY event_groups.organization_id, efforts.person_id
), latest_vmulti AS (
SELECT ranked_vmultis.organization_id,
ranked_vmultis.person_id,
ranked_vmultis.year AS latest_vmulti_year,
ranked_vmultis.quantity AS latest_vmulti_year_count
FROM ( SELECT historical_facts.organization_id,
historical_facts.person_id,
historical_facts.year,
historical_facts.quantity,
row_number() OVER (PARTITION BY historical_facts.organization_id, historical_facts.person_id ORDER BY historical_facts.year DESC) AS rank
FROM historical_facts
WHERE ((historical_facts.kind = 3) AND (historical_facts.year < 2024))) ranked_vmultis
WHERE (ranked_vmultis.rank = 1)
), volunteer_year_count AS (
SELECT historical_facts.organization_id,
historical_facts.person_id,
count(*) AS volunteer_year_count
FROM (historical_facts
LEFT JOIN latest_vmulti latest_vmulti_1 USING (organization_id, person_id))
WHERE ((historical_facts.kind = 1) AND (historical_facts.year < 2025) AND (historical_facts.year > latest_vmulti_1.latest_vmulti_year))
GROUP BY historical_facts.organization_id, historical_facts.person_id
), major_volunteer_year_count AS (
SELECT historical_facts.organization_id,
historical_facts.person_id,
1 AS major_volunteer_year_count
FROM historical_facts
WHERE ((historical_facts.kind = 2) AND (historical_facts.year = 2024))
)
SELECT applicants.organization_id,
applicants.person_id,
CASE
WHEN ((applicants.gender = 0) AND applicants.finisher) THEN 'Male Finishers'::text
WHEN (applicants.gender = 0) THEN 'Male Nevers'::text
WHEN applicants.finisher THEN 'Female Finishers'::text
ELSE 'Female Nevers'::text
END AS division,
CASE
WHEN applicants.finisher THEN (((((COALESCE(dns_since_last_start_count.dns_since_last_start_count, (0)::bigint) + COALESCE(finish_year_count.finish_year_count, (0)::bigint)) + ((COALESCE(volunteer_year_count.volunteer_year_count, (0)::bigint) + COALESCE(latest_vmulti.latest_vmulti_year_count, 0)) / 5)) + COALESCE(major_volunteer_year_count.major_volunteer_year_count, 0)) + 1))::double precision
ELSE pow((2)::double precision, ((((COALESCE(dns_since_last_reset_count.dns_since_last_reset_count, (0)::bigint) + COALESCE(finish_year_count.finish_year_count, (0)::bigint)) + ((COALESCE(volunteer_year_count.volunteer_year_count, (0)::bigint) + COALESCE(latest_vmulti.latest_vmulti_year_count, 0)) / 5)) + COALESCE(major_volunteer_year_count.major_volunteer_year_count, 0)))::double precision)
END AS ticket_count
FROM ((((((applicants
LEFT JOIN dns_since_last_start_count USING (organization_id, person_id))
LEFT JOIN dns_since_last_reset_count USING (organization_id, person_id))
LEFT JOIN finish_year_count USING (organization_id, person_id))
LEFT JOIN latest_vmulti USING (organization_id, person_id))
LEFT JOIN volunteer_year_count USING (organization_id, person_id))
LEFT JOIN major_volunteer_year_count USING (organization_id, person_id));
SQL
end
133 changes: 133 additions & 0 deletions db/views/lottery_ticket_calc_hardrock_2025s_v01.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
with applicants as (
select historical_facts.organization_id,
historical_facts.person_id,
any_value(historical_facts.gender) as gender,
coalesce(bool_or(event_groups.organization_id = historical_facts.organization_id and
(efforts.finished or (efforts.started and extract(year from events.scheduled_start_time) < 2021))),
false) as finisher
from historical_facts
left join efforts on efforts.person_id = historical_facts.person_id
left join events on events.id = efforts.event_id
left join event_groups on event_groups.id = events.event_group_id
where kind = 11
and year = 2024
group by historical_facts.organization_id, historical_facts.person_id
),

last_start_year as (
select organization_id, person_id, max(extract(year from events.scheduled_start_time)) as year
from efforts
join events on events.id = efforts.event_id
join event_groups on event_groups.id = events.event_group_id
where efforts.started
group by organization_id, person_id
order by person_id
),

dns_since_last_start_count as (
select historical_facts.organization_id, historical_facts.person_id, count(*) as dns_since_last_start_count
from historical_facts
left join last_start_year using (organization_id, person_id)
where historical_facts.kind = 0
and historical_facts.year < 2025
and historical_facts.year > coalesce(last_start_year.year, 0)
group by historical_facts.organization_id, historical_facts.person_id
),

last_reset_year as (
select organization_id, person_id, max(extract(year from events.scheduled_start_time)) as year
from efforts
join events on events.id = efforts.event_id
join event_groups on event_groups.id = events.event_group_id
where efforts.finished
or (efforts.started and extract(year from events.scheduled_start_time) > 2023)
group by organization_id, person_id
),

dns_since_last_reset_count as (
select historical_facts.organization_id, historical_facts.person_id, count(*) as dns_since_last_reset_count
from historical_facts
left join last_reset_year using (organization_id, person_id)
where historical_facts.kind = 0
and historical_facts.year < 2025
and historical_facts.year > coalesce(last_reset_year.year, 0)
group by historical_facts.organization_id, historical_facts.person_id
),

finish_year_count as (
select organization_id, person_id, count(*) as finish_year_count
from efforts
join events on events.id = efforts.event_id
join event_groups on event_groups.id = events.event_group_id
where efforts.finished
and extract(year from events.scheduled_start_time) < 2025
group by organization_id, person_id
),

latest_vmulti as (
select ranked_vmultis.organization_id,
ranked_vmultis.person_id,
ranked_vmultis.year as latest_vmulti_year,
ranked_vmultis.quantity as latest_vmulti_year_count
from (
select historical_facts.organization_id,
historical_facts.person_id,
historical_facts.year,
historical_facts.quantity,
row_number()
over (partition by historical_facts.organization_id, historical_facts.person_id order by historical_facts.year desc) as rank
from historical_facts
where historical_facts.kind = 3
and historical_facts.year < 2024
) ranked_vmultis
where rank = 1
),

volunteer_year_count as (
select historical_facts.organization_id, historical_facts.person_id, count(*) as volunteer_year_count
from historical_facts
left join latest_vmulti using (organization_id, person_id)
where kind = 1
and year < 2025
and year > latest_vmulti_year
group by historical_facts.organization_id, historical_facts.person_id
),

major_volunteer_year_count as (
select historical_facts.organization_id, historical_facts.person_id, 1 as major_volunteer_year_count
from historical_facts
where historical_facts.kind = 2
and historical_facts.year = 2024
)

select applicants.organization_id,
applicants.person_id,
case
when gender = 0 and finisher then 'Male Finishers'
when gender = 0 then 'Male Nevers'
when finisher then 'Female Finishers'
else 'Female Nevers'
end as division,
case
when finisher
then coalesce(dns_since_last_start_count, 0) +
coalesce(finish_year_count, 0) +
(coalesce(volunteer_year_count, 0) + coalesce(latest_vmulti_year_count, 0)) / 5 +
coalesce(major_volunteer_year_count, 0) +
1
else pow(2,
coalesce(dns_since_last_reset_count, 0) +
coalesce(finish_year_count, 0) +
(coalesce(volunteer_year_count, 0) + coalesce(latest_vmulti_year_count, 0)) / 5 +
coalesce(major_volunteer_year_count, 0)
)
end as ticket_count

from applicants
natural left join dns_since_last_start_count
natural left join dns_since_last_reset_count
natural left join finish_year_count
natural left join latest_vmulti
natural left join volunteer_year_count
natural left join major_volunteer_year_count
;
Binary file modified erd.pdf
Binary file not shown.

0 comments on commit 54587a0

Please sign in to comment.