| 1 | BEGIN;
|
|---|
| 2 |
|
|---|
| 3 | WITH
|
|---|
| 4 | db_horizon AS (
|
|---|
| 5 | SELECT MAX(match_date) AS latest_match FROM "match"
|
|---|
| 6 | ),
|
|---|
| 7 |
|
|---|
| 8 | appearances 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 |
|
|---|
| 20 | pts 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 |
|
|---|
| 30 | ranked 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 | ),
|
|---|
| 39 | primary_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 |
|
|---|
| 45 | ordered 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 | ),
|
|---|
| 52 | flagged 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 | ),
|
|---|
| 58 | grouped 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 |
|
|---|
| 69 | stints 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 |
|
|---|
| 81 | stints_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 |
|
|---|
| 90 | windowed 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 |
|
|---|
| 100 | with_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 |
|
|---|
| 123 | final 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 |
|
|---|
| 157 | INSERT INTO Player_contract
|
|---|
| 158 | (player_id, team_id, season_id, contract_value, start_date, end_date)
|
|---|
| 159 | SELECT
|
|---|
| 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
|
|---|
| 166 | FROM final f
|
|---|
| 167 | WHERE 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 | )
|
|---|
| 173 | AND 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 |
|
|---|
| 181 | COMMIT; |
|---|