DatabaseCreation: contract_generator.sql

File contract_generator.sql, 5.1 KB (added by 231091, 5 hours ago)
Line 
1BEGIN;
2
3WITH
4db_horizon AS (
5 SELECT MAX(match_date) AS latest_match FROM "match"
6),
7
8appearances AS (
9 SELECT
10 l.player_id,
11 l.team_id,
12 m.season_id,
13 m.match_date
14 FROM Lineup l
15 JOIN "match" m ON m.match_id = l.match_id
16 JOIN Team t ON t.team_id = l.team_id
17 WHERE t.country IS DISTINCT FROM 'International'
18),
19
20pts AS (
21 SELECT
22 player_id, team_id, season_id,
23 MIN(match_date) AS first_match,
24 MAX(match_date) AS last_match,
25 COUNT(*) AS apps
26 FROM appearances
27 GROUP BY player_id, team_id, season_id
28),
29
30ranked AS (
31 SELECT
32 pts.*,
33 ROW_NUMBER() OVER (
34 PARTITION BY player_id, season_id
35 ORDER BY apps DESC, last_match DESC
36 ) AS rn
37 FROM pts
38),
39primary_team_per_season AS (
40 SELECT player_id, team_id, season_id, first_match, last_match
41 FROM ranked
42 WHERE rn = 1
43),
44
45ordered AS (
46 SELECT
47 p.*,
48 ROW_NUMBER() OVER (PARTITION BY player_id ORDER BY first_match) AS seq,
49 LAG(team_id) OVER (PARTITION BY player_id ORDER BY first_match) AS prev_team
50 FROM primary_team_per_season p
51),
52flagged AS (
53 SELECT
54 o.*,
55 CASE WHEN prev_team IS DISTINCT FROM team_id THEN 1 ELSE 0 END AS new_stint
56 FROM ordered o
57),
58grouped AS (
59 SELECT
60 f.*,
61 SUM(new_stint) OVER (
62 PARTITION BY player_id
63 ORDER BY seq
64 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
65 ) AS stint_no
66 FROM flagged f
67),
68
69stints AS (
70 SELECT
71 player_id,
72 team_id,
73 stint_no,
74 MIN(first_match) AS stint_first_match,
75 MAX(last_match) AS stint_last_match,
76 (ARRAY_AGG(season_id ORDER BY first_match))[1] AS anchor_season_id
77 FROM grouped
78 GROUP BY player_id, team_id, stint_no
79),
80
81stints_with_next AS (
82 SELECT
83 s.*,
84 LEAD(stint_first_match) OVER (
85 PARTITION BY player_id ORDER BY stint_no
86 ) AS next_stint_start
87 FROM stints s
88),
89
90windowed AS (
91 SELECT
92 sn.*,
93 (sn.stint_first_match
94 - ((14 + floor(random() * 43))::int) * INTERVAL '1 day'
95 )::date AS start_date_raw,
96 (4 + floor(random() * 6))::int AS target_years
97 FROM stints_with_next sn
98),
99
100with_dates AS (
101 SELECT
102 w.player_id,
103 w.team_id,
104 w.anchor_season_id,
105 w.stint_first_match,
106 w.stint_last_match,
107 w.next_stint_start,
108 w.start_date_raw AS start_date,
109 (w.start_date_raw + (w.target_years || ' years')::INTERVAL)::date
110 AS desired_end_by_length,
111 CASE
112 WHEN w.next_stint_start IS NULL THEN NULL
113 ELSE (w.next_stint_start
114 - ((14 + floor(random() * 57))::int) * INTERVAL '1 day'
115 )::date
116 END AS hard_cap_end,
117 (w.stint_last_match
118 + ((30 + floor(random() * 151))::int) * INTERVAL '1 day'
119 )::date AS soft_min_end
120 FROM windowed w
121),
122
123final AS (
124 SELECT
125 d.player_id,
126 d.team_id,
127 d.anchor_season_id AS season_id,
128 d.stint_first_match,
129 d.stint_last_match,
130 d.start_date,
131 CASE
132 WHEN d.hard_cap_end IS NOT NULL THEN
133 CASE
134 WHEN LEAST(
135 GREATEST(d.desired_end_by_length, d.soft_min_end),
136 d.hard_cap_end
137 ) > d.start_date
138 THEN LEAST(
139 GREATEST(d.desired_end_by_length, d.soft_min_end),
140 d.hard_cap_end
141 )
142 WHEN d.hard_cap_end > d.start_date THEN d.hard_cap_end
143 ELSE (d.stint_last_match + INTERVAL '1 day')::date
144 END
145 WHEN (SELECT latest_match FROM db_horizon)
146 - d.stint_last_match <= 240 THEN NULL
147 ELSE
148 CASE
149 WHEN GREATEST(d.desired_end_by_length, d.soft_min_end) > d.start_date
150 THEN GREATEST(d.desired_end_by_length, d.soft_min_end)
151 ELSE (d.stint_last_match + INTERVAL '1 day')::date
152 END
153 END AS end_date
154 FROM with_dates d
155)
156
157INSERT INTO Player_contract
158 (player_id, team_id, season_id, contract_value, start_date, end_date)
159SELECT
160 f.player_id,
161 f.team_id,
162 f.season_id,
163 ROUND( (50000 + random() * 24950000)::numeric, 2 ) AS contract_value,
164 f.start_date,
165 f.end_date
166FROM final f
167WHERE NOT EXISTS (
168 SELECT 1 FROM Player_contract pc
169 WHERE pc.player_id = f.player_id
170 AND pc.team_id = f.team_id
171 AND pc.season_id = f.season_id
172)
173AND NOT EXISTS (
174 SELECT 1 FROM Player_contract pc2
175 WHERE pc2.player_id = f.player_id
176 AND pc2.team_id <> f.team_id
177 AND pc2.start_date <= COALESCE(f.end_date, DATE '9999-12-31')
178 AND COALESCE(pc2.end_date, DATE '9999-12-31') >= f.start_date
179);
180
181COMMIT;