-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0001_mobsMatchesAndRating.sql
More file actions
212 lines (204 loc) · 7.01 KB
/
0001_mobsMatchesAndRating.sql
File metadata and controls
212 lines (204 loc) · 7.01 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
create table mm_mobs
(
id serial
constraint mobs_pk
primary key,
name varchar(255) not null,
image varchar(255) not null,
created timestamp default CURRENT_TIMESTAMP not null,
enabled boolean default true not null
);
create table mm_matches
(
id bigserial,
mob1fk integer not null
constraint matches_mob1_fk
references mm_mobs,
mob2fk integer not null
constraint matches_mob2_fk
references mm_mobs,
created timestamp default CURRENT_TIMESTAMP not null,
winner integer not null,
session varchar(255)
);
create table mm_history_cache
(
ratings jsonb not null,
last_update bigint not null
);
CREATE VIEW mm_matches_of_mob(id, mob, opponent, won, created) AS
SELECT mm_matches.id,
mm_matches.mob1fk AS mob,
mm_matches.mob2fk AS opponent,
mm_matches.winner = 1 AS won,
mm_matches.created,
mm_matches.session
FROM mm_matches
UNION
SELECT mm_matches.id,
mm_matches.mob2fk AS mob,
mm_matches.mob1fk AS opponent,
mm_matches.winner = 2 AS won,
mm_matches.created,
mm_matches.session
FROM mm_matches;
CREATE VIEW mm_rating_history(ratings, last_update) AS
WITH RECURSIVE ratings_history (ratings, last_update) AS (
WITH ratings_seed (ratings, last_update) AS (
SELECT
jsonb_object_agg(id, start_value) AS ratings,
0::bigint AS last_update
FROM mm_mobs
CROSS JOIN
(
SELECT
1500 AS start_value
) AS start_value
WHERE enabled
UNION ALL
SELECT
ratings,
last_update
FROM mm_history_cache
)
SELECT
ratings,
last_update
FROM ratings_seed
WHERE
last_update = (
SELECT max(last_update) FROM ratings_seed
)
UNION ALL
SELECT
jsonb_set(
jsonb_set(
ratings,
ARRAY[mob1::text],
to_jsonb(mob1rating)
),
ARRAY[mob2::text],
to_jsonb(mob2rating)
) AS ratings,
next_match AS last_update
FROM
(
SELECT
next_match,
ratings,
mob1,
mob2,
winner,
mob1rating + 32::numeric * (
CASE
WHEN winner = 1 THEN 1
ELSE 0
END::numeric - expectation_for_mob1
) AS mob1rating,
mob2rating + 32::numeric * (
CASE
WHEN winner = 2 THEN 1
ELSE 0
END::numeric - (1 - expectation_for_mob1)
) AS mob2rating
FROM
(
SELECT
next_match,
ratings,
mob1,
mob2,
winner,
mob1rating,
mob2rating,
(1::numeric /
(1::numeric + power(
10::numeric,
(mob2rating - mob1rating) / 400::numeric
))
) AS expectation_for_mob1
FROM
(
SELECT
next_match.id AS next_match,
next_match.ratings AS ratings,
mm_matches.mob1fk AS mob1,
mm_matches.mob2fk AS mob2,
mm_matches.winner AS winner,
cast(next_match.ratings->cast(mm_matches.mob1fk AS varchar) AS numeric) AS mob1rating,
cast(next_match.ratings->cast(mm_matches.mob2fk AS varchar) AS numeric) AS mob2rating
FROM
(
SELECT
mm_matches.id,
ratings_history.ratings
FROM ratings_history
CROSS JOIN mm_matches
INNER JOIN mm_mobs AS mob
ON mob.id = mm_matches.mob1fk
INNER JOIN mm_mobs AS opponent
ON opponent.id = mm_matches.mob1fk
WHERE mm_matches.id > ratings_history.last_update
AND mob.enabled
AND opponent.enabled
ORDER BY mm_matches.id ASC
LIMIT 1
) AS next_match
INNER JOIN mm_matches
ON mm_matches.id = next_match.id
) AS match_with_ratings
) AS expectation
) AS new_ratings
)
SELECT * from ratings_history;
CREATE VIEW mm_current_rating(mob, rating) AS
SELECT
cast(key as numeric) as mob,
cast(value as numeric) as rating
FROM jsonb_each(
(
SELECT
ratings
FROM mm_rating_history
WHERE last_update = (
SELECT max(last_update)
FROM mm_rating_history
)
)
);
CREATE VIEW mm_rating_trends (mob, rating, "date", id) AS
SELECT
cast(key AS numeric) AS mob,
cast(value AS numeric) rating,
"date",
id
FROM (
SELECT
id,
ratings,
"date"
FROM (
SELECT
max(id) AS id,
"date"
FROM (
SELECT
last_update AS id,
date(matches.created) AS "date"
FROM mm_history_cache AS history
INNER JOIN mm_matches AS matches
ON history.last_update = matches.id
) AS dates
GROUP BY "date"
) AS key_dates
INNER JOIN mm_history_cache AS history
ON key_dates.id = history.last_update
) AS ratings_at_key_date,
jsonb_each(ratings_at_key_date.ratings) AS ratings(key, value);
create table mm_audit_log
(
time timestamp default CURRENT_TIMESTAMP not null,
session varchar(255) not null,
event varchar(255) not null,
details text
);