| | 11 | |
| | 12 | = Фаза 2б — Погледи (Views) |
| | 13 | |
| | 14 | == vw_election_results |
| | 15 | |
| | 16 | Го прикажува збирниот изборен резултат по политички ентитет за секој избор — вклучувајќи вкупен број гласови, процент, и дали ентитетот го поминал 5% цензусот. Ја имплементира бизнис логиката за јавно објавување на официјални изборни резултати и овозможува брза споредба на перформансите на партиите и коалициите по избор. |
| | 17 | |
| | 18 | {{{ |
| | 19 | CREATE OR REPLACE VIEW public.vw_election_results AS |
| | 20 | WITH election_totals AS ( |
| | 21 | SELECT vote_result.election_id, |
| | 22 | sum(vote_result.votes) AS total_valid_votes |
| | 23 | FROM vote_result |
| | 24 | GROUP BY vote_result.election_id |
| | 25 | ), |
| | 26 | entity_votes AS ( |
| | 27 | SELECT vote_result.election_id, |
| | 28 | vote_result.entity_id, |
| | 29 | sum(vote_result.votes) AS total_votes |
| | 30 | FROM vote_result |
| | 31 | WHERE vote_result.candidate_id IS NULL |
| | 32 | GROUP BY vote_result.election_id, vote_result.entity_id |
| | 33 | ), |
| | 34 | calc AS ( |
| | 35 | SELECT ev.election_id, |
| | 36 | ev.entity_id, |
| | 37 | ev.total_votes, |
| | 38 | el.total_valid_votes, |
| | 39 | ev.total_votes::numeric * 100.0 / NULLIF(el.total_valid_votes, 0)::numeric AS vote_pct |
| | 40 | FROM entity_votes ev |
| | 41 | JOIN election_totals el USING (election_id) |
| | 42 | ) |
| | 43 | SELECT e.election_id, |
| | 44 | e.name AS election_name, |
| | 45 | e.election_date, |
| | 46 | et.type_name AS election_type, |
| | 47 | pe.entity_id, |
| | 48 | pe.name AS entity_name, |
| | 49 | pe.type AS entity_type, |
| | 50 | c.total_votes, |
| | 51 | c.total_valid_votes, |
| | 52 | round(c.vote_pct, 2) AS vote_share_pct, |
| | 53 | c.vote_pct >= 5.0 AS passed_threshold, |
| | 54 | wm.method_name AS winner_method |
| | 55 | FROM calc c |
| | 56 | JOIN election e USING (election_id) |
| | 57 | JOIN election_type et ON et.election_type_id = e.election_type_id |
| | 58 | JOIN winner_method wm ON wm.method_id = e.winner_method_id |
| | 59 | JOIN political_entity pe USING (entity_id); |
| | 60 | }}} |
| | 61 | |
| | 62 | ---- |
| | 63 | |
| | 64 | == vw_dhondt_seat_allocation |
| | 65 | |
| | 66 | Ја пресметува распределбата на парламентарни мандати по изборна единица користејќи D'Hondt метод, со вграден 5% праг и поддршка за коалиции. Ја имплементира законски задолжителната пропорционална распределба на мандати за парламентарни избори и овозможува транспарентен увид во тоа колку мандати освоил секој ентитет по регион. |
| | 67 | |
| | 68 | {{{ |
| | 69 | CREATE OR REPLACE VIEW public.vw_dhondt_seat_allocation AS |
| | 70 | WITH district_votes AS ( |
| | 71 | SELECT ed.district_id, ed.election_id, ed.region_id, ed.seats_available, |
| | 72 | vr.entity_id, sum(vr.votes) AS district_votes |
| | 73 | FROM electoral_district ed |
| | 74 | JOIN election e_1 ON e_1.election_id = ed.election_id |
| | 75 | JOIN vote_result vr ON vr.election_id = ed.election_id |
| | 76 | JOIN polling_station ps ON ps.station_id = vr.station_id |
| | 77 | JOIN region r2 ON r2.region_id = ps.municipality_id |
| | 78 | WHERE e_1.winner_method_id = 8 |
| | 79 | AND vr.candidate_id IS NULL |
| | 80 | AND (r2.region_id = ed.region_id OR r2.parent_region_id = ed.region_id) |
| | 81 | GROUP BY ed.district_id, ed.election_id, ed.region_id, ed.seats_available, vr.entity_id |
| | 82 | ), |
| | 83 | district_totals AS ( |
| | 84 | SELECT district_id, sum(district_votes) AS total_district_votes FROM district_votes GROUP BY district_id |
| | 85 | ), |
| | 86 | eligible AS ( |
| | 87 | SELECT dv.*, dt.total_district_votes, |
| | 88 | dv.district_votes::numeric * 100.0 / NULLIF(dt.total_district_votes, 0::numeric) AS vote_pct |
| | 89 | FROM district_votes dv JOIN district_totals dt USING (district_id) |
| | 90 | WHERE (dv.district_votes::numeric * 100.0 / NULLIF(dt.total_district_votes, 0::numeric)) >= 5.0 |
| | 91 | ), |
| | 92 | dhondt AS ( |
| | 93 | SELECT e_1.*, d.divisor, |
| | 94 | e_1.district_votes::numeric / d.divisor::numeric AS quotient |
| | 95 | FROM eligible e_1 CROSS JOIN LATERAL generate_series(1, e_1.seats_available) d(divisor) |
| | 96 | ), |
| | 97 | ranked AS ( |
| | 98 | SELECT *, rank() OVER (PARTITION BY district_id ORDER BY quotient DESC) AS rn FROM dhondt |
| | 99 | ), |
| | 100 | seats AS ( |
| | 101 | SELECT district_id, election_id, region_id, seats_available, entity_id, |
| | 102 | district_votes, total_district_votes, vote_pct, |
| | 103 | count(*) FILTER (WHERE rn <= seats_available) AS seats_won |
| | 104 | FROM ranked |
| | 105 | GROUP BY district_id, election_id, region_id, seats_available, entity_id, |
| | 106 | district_votes, total_district_votes, vote_pct |
| | 107 | ) |
| | 108 | SELECT s.election_id, e.name AS election_name, e.election_date, |
| | 109 | s.district_id, r.name AS region_name, s.seats_available, |
| | 110 | s.entity_id, pe.name AS entity_name, pe.type AS entity_type, |
| | 111 | s.district_votes AS total_votes, s.total_district_votes, |
| | 112 | round(s.vote_pct, 2) AS vote_share_pct, s.seats_won |
| | 113 | FROM seats s |
| | 114 | JOIN election e USING (election_id) |
| | 115 | JOIN region r ON r.region_id = s.region_id |
| | 116 | JOIN political_entity pe USING (entity_id) |
| | 117 | ORDER BY s.election_id, s.district_id, s.seats_won DESC; |
| | 118 | }}} |
| | 119 | |
| | 120 | ---- |
| | 121 | |
| | 122 | == vw_invalid_ballot_analysis |
| | 123 | |
| | 124 | Прикажува статистика за невалидни гласачки ливчиња по избор и општина — вкупен број ливчиња, број невалидни и процент. Ја имплементира логиката за надзор на квалитетот на изборниот процес, овозможувајќи лесна идентификација на општини со висок процент невалидни ливчиња кои бараат дополнителна анализа. |
| | 125 | |
| | 126 | {{{ |
| | 127 | CREATE OR REPLACE VIEW public.vw_invalid_ballot_analysis AS |
| | 128 | SELECT e.election_id, |
| | 129 | e.name AS election_name, |
| | 130 | r.region_id, |
| | 131 | r.name AS region_name, |
| | 132 | count(*) AS total_ballots, |
| | 133 | count(*) FILTER (WHERE NOT b.is_valid) AS invalid_ballots, |
| | 134 | round(count(*) FILTER (WHERE NOT b.is_valid)::numeric * 100.0 |
| | 135 | / NULLIF(count(*), 0)::numeric, 2) AS invalid_pct |
| | 136 | FROM ballot b |
| | 137 | JOIN election e ON e.election_id = b.election_id |
| | 138 | JOIN polling_station ps ON ps.station_id = b.station_id |
| | 139 | JOIN region r ON r.region_id = ps.municipality_id |
| | 140 | GROUP BY e.election_id, e.name, r.region_id, r.name; |
| | 141 | }}} |
| | 142 | |
| | 143 | ---- |
| | 144 | |
| | 145 | == vw_local_election_winners |
| | 146 | |
| | 147 | Го прикажува победникот на локалните избори (тип 3) по општина — партијата со најмногу гласови во секоја општина. Ја имплементира бизнис логиката за прогласување победник на локалните избори по принцип на релативно мнозинство, и овозможува брз преглед на политичката карта по општини. |
| | 148 | |
| | 149 | {{{ |
| | 150 | CREATE OR REPLACE VIEW public.vw_local_election_winners AS |
| | 151 | WITH totalvotesperparty AS ( |
| | 152 | SELECT vr.election_id, e.name AS election_name, r.name AS municipality_name, |
| | 153 | pe.name AS party_name, sum(vr.votes) AS total_sum_votes |
| | 154 | FROM vote_result vr |
| | 155 | JOIN election e ON vr.election_id = e.election_id |
| | 156 | JOIN political_entity pe ON vr.entity_id = pe.entity_id |
| | 157 | JOIN polling_station ps ON vr.station_id = ps.station_id |
| | 158 | JOIN region r ON ps.municipality_id = r.region_id |
| | 159 | WHERE e.election_type_id = 3 |
| | 160 | GROUP BY vr.election_id, e.name, r.name, pe.name |
| | 161 | ), |
| | 162 | rankedwinners AS ( |
| | 163 | SELECT *, rank() OVER (PARTITION BY election_id, municipality_name ORDER BY total_sum_votes DESC) AS rnk |
| | 164 | FROM totalvotesperparty |
| | 165 | ) |
| | 166 | SELECT election_name, municipality_name, |
| | 167 | party_name AS winner_name, |
| | 168 | total_sum_votes AS votes_received, |
| | 169 | 'Winner'::text AS status |
| | 170 | FROM rankedwinners |
| | 171 | WHERE rnk = 1; |
| | 172 | }}} |
| | 173 | |
| | 174 | ---- |
| | 175 | |
| | 176 | == vw_parliamentary_municipality_winners |
| | 177 | |
| | 178 | Го прикажува доминантниот политички ентитет по општина за парламентарни избори (тип 2), врз основа на агрегирани гласови по гласачко место. Ја имплементира логиката за визуелизација на изборната карта на парламентарни избори — корисна за анализа на регионалната доминација на партиите и медиумско известување. |
| | 179 | |
| | 180 | {{{ |
| | 181 | CREATE OR REPLACE VIEW public.vw_parliamentary_municipality_winners AS |
| | 182 | WITH aggregatedvotes AS ( |
| | 183 | SELECT e.election_id, e.name AS election_name, r.name AS municipality_name, |
| | 184 | pe.name AS party_name, sum(vr.votes) AS total_votes |
| | 185 | FROM vote_result vr |
| | 186 | JOIN election e ON vr.election_id = e.election_id |
| | 187 | JOIN political_entity pe ON vr.entity_id = pe.entity_id |
| | 188 | JOIN polling_station ps ON vr.station_id = ps.station_id |
| | 189 | JOIN region r ON ps.municipality_id = r.region_id |
| | 190 | WHERE e.election_type_id = 2 |
| | 191 | GROUP BY e.election_id, e.name, r.name, pe.name |
| | 192 | ), |
| | 193 | rankedwinners AS ( |
| | 194 | SELECT *, rank() OVER (PARTITION BY election_id, municipality_name ORDER BY total_votes DESC) AS pos |
| | 195 | FROM aggregatedvotes |
| | 196 | ) |
| | 197 | SELECT election_name, municipality_name, |
| | 198 | party_name AS dominant_party, |
| | 199 | total_votes AS winning_votes, |
| | 200 | 'Municipality Winner'::text AS status |
| | 201 | FROM rankedwinners |
| | 202 | WHERE pos = 1; |
| | 203 | }}} |
| | 204 | |
| | 205 | ---- |
| | 206 | |
| | 207 | == vw_party_demographic_performance |
| | 208 | |
| | 209 | Ги прикажува гласовите по политички ентитет и гласачко место разбиени по генерациски кохорти: Gen Z (роден ≥1996), Милениалци (1981–1995) и Сениори (<1981). Ја имплементира логиката за демографска анализа на изборна поддршка, овозможувајќи партиите и истражувачите да ја разберат старосната структура на гласачкото тело по регион. |
| | 210 | |
| | 211 | {{{ |
| | 212 | CREATE OR REPLACE VIEW public.vw_party_demographic_performance AS |
| | 213 | WITH VoterDemographics AS ( |
| | 214 | |
| | 215 | SELECT |
| | 216 | ve.election_id, |
| | 217 | ve.station_id, |
| | 218 | p.date_of_birth, |
| | 219 | EXTRACT(YEAR FROM p.date_of_birth) as birth_year |
| | 220 | FROM public.voter_election ve |
| | 221 | JOIN public.voter v ON ve.voter_id = v.voter_id |
| | 222 | JOIN public.person p ON v.person_id = p.person_id |
| | 223 | ), |
| | 224 | BallotStats AS ( |
| | 225 | |
| | 226 | SELECT |
| | 227 | b.election_id, |
| | 228 | b.station_id, |
| | 229 | b.entity_id, |
| | 230 | b.ballot_id |
| | 231 | FROM public.ballot b |
| | 232 | WHERE b.is_valid = true |
| | 233 | ) |
| | 234 | SELECT |
| | 235 | e.name AS election_name, |
| | 236 | r.name AS region_name, |
| | 237 | pe.name AS party_name, |
| | 238 | ps.name AS station_name, |
| | 239 | |
| | 240 | COALESCE(COUNT(CASE WHEN vd.birth_year >= 1996 THEN 1 END), 0) AS gen_z_votes, |
| | 241 | COALESCE(COUNT(CASE WHEN vd.birth_year >= 1981 AND vd.birth_year <= 1995 THEN 1 END), 0) AS millennial_votes, |
| | 242 | COALESCE(COUNT(CASE WHEN vd.birth_year < 1981 THEN 1 END), 0) AS senior_votes, |
| | 243 | COUNT(bs.ballot_id) AS total_valid_votes |
| | 244 | FROM BallotStats bs |
| | 245 | JOIN public.election e ON bs.election_id = e.election_id |
| | 246 | JOIN public.polling_station ps ON bs.station_id = ps.station_id |
| | 247 | JOIN public.region r ON ps.municipality_id = r.region_id |
| | 248 | JOIN public.political_entity pe ON bs.entity_id = pe.entity_id |
| | 249 | |
| | 250 | LEFT JOIN VoterDemographics vd ON bs.election_id = vd.election_id |
| | 251 | AND bs.station_id = vd.station_id |
| | 252 | GROUP BY e.name, r.name, pe.name, ps.name; |
| | 253 | }}} |
| | 254 | |
| | 255 | ---- |
| | 256 | |
| | 257 | == vw_party_performance_over_time |
| | 258 | |
| | 259 | Ги следи гласовите и процентот на поддршка за секој политички ентитет низ повеќе изборни циклуси, подредени по ентитет и датум. Ја имплементира логиката за временска анализа на трендови во изборна поддршка — суштинска алатка за политичка аналитика, истражување и споредба на резултати меѓу последователни избори. |
| | 260 | |
| | 261 | {{{ |
| | 262 | CREATE OR REPLACE VIEW public.vw_party_performance_over_time AS |
| | 263 | WITH party_votes AS ( |
| | 264 | SELECT e.election_id, e.name AS election_name, e.election_date, |
| | 265 | pe.entity_id, pe.name AS entity_name, sum(vr.votes) AS total_votes |
| | 266 | FROM vote_result vr |
| | 267 | JOIN election e ON e.election_id = vr.election_id |
| | 268 | JOIN political_entity pe ON pe.entity_id = vr.entity_id |
| | 269 | WHERE vr.candidate_id IS NULL |
| | 270 | GROUP BY e.election_id, e.name, e.election_date, pe.entity_id, pe.name |
| | 271 | ), |
| | 272 | totals AS ( |
| | 273 | SELECT election_id, sum(total_votes) AS total_election_votes FROM party_votes GROUP BY election_id |
| | 274 | ) |
| | 275 | SELECT pv.election_id, pv.election_name, pv.election_date, |
| | 276 | pv.entity_id, pv.entity_name, pv.total_votes, t.total_election_votes, |
| | 277 | round(pv.total_votes::numeric * 100.0 / NULLIF(t.total_election_votes, 0::numeric), 2) AS vote_share_pct |
| | 278 | FROM party_votes pv JOIN totals t USING (election_id) |
| | 279 | ORDER BY pv.entity_name, pv.election_date; |
| | 280 | }}} |
| | 281 | |
| | 282 | ---- |
| | 283 | |
| | 284 | == vw_polling_station_stats |
| | 285 | |
| | 286 | Дава детална статистика по гласачко место за секој избор — регистрирани гласачи, фрлени ливчиња, валидни, невалидни и процент на излезност. Ја имплементира логиката за оперативен мониторинг на изборниот ден, овозможувајќи увид во активноста на секоја поединечна станица во реално време. |
| | 287 | |
| | 288 | {{{ |
| | 289 | CREATE OR REPLACE VIEW public.vw_polling_station_stats AS |
| | 290 | SELECT e.election_id, |
| | 291 | e.name AS election_name, |
| | 292 | ps.station_id, |
| | 293 | ps.name AS station_name, |
| | 294 | count(DISTINCT v.voter_id) AS registered_voters, |
| | 295 | count(b.ballot_id) AS ballots_cast, |
| | 296 | count(b.ballot_id) FILTER (WHERE b.is_valid) AS valid_ballots, |
| | 297 | count(b.ballot_id) FILTER (WHERE NOT b.is_valid) AS invalid_ballots, |
| | 298 | round(count(b.ballot_id)::numeric * 100.0 |
| | 299 | / NULLIF(count(DISTINCT v.voter_id), 0)::numeric, 2) AS turnout_pct |
| | 300 | FROM polling_station ps |
| | 301 | JOIN station_election se ON se.station_id = ps.station_id |
| | 302 | JOIN election e ON e.election_id = se.election_id |
| | 303 | LEFT JOIN ballot b ON b.station_id = ps.station_id AND b.election_id = e.election_id |
| | 304 | LEFT JOIN voter v ON v.station_id = ps.station_id |
| | 305 | GROUP BY e.election_id, e.name, ps.station_id, ps.name; |
| | 306 | }}} |
| | 307 | |
| | 308 | ---- |
| | 309 | |
| | 310 | == vw_polling_station_voter_count |
| | 311 | |
| | 312 | Прикажува точен број на регистрирани гласачи по гласачко место и регион, пресметан директно од табелата `voter`. Служи за верификација на конзистентноста на податоците — споредувајќи го овој поглед со полето `registered_voter` во `polling_station` може да се откријат евентуални несогласувања во бројачите. |
| | 313 | |
| | 314 | {{{ |
| | 315 | CREATE OR REPLACE VIEW public.vw_polling_station_voter_count AS |
| | 316 | SELECT r.name AS region_name, |
| | 317 | ps.name AS station_name, |
| | 318 | count(v.voter_id) AS actual_registered_voters |
| | 319 | FROM polling_station ps |
| | 320 | JOIN region r ON ps.municipality_id = r.region_id |
| | 321 | LEFT JOIN voter v ON ps.station_id = v.station_id |
| | 322 | GROUP BY r.name, ps.name; |
| | 323 | }}} |
| | 324 | |
| | 325 | ---- |
| | 326 | |
| | 327 | == vw_presidential_by_municipality |
| | 328 | |
| | 329 | Го прикажува водечкиот кандидат на претседателски избори (тип 1) по општина, врз основа на вкупни гласови. Ја имплементира логиката за регионална анализа на претседателски избори — овозможува визуелизација на изборната карта и увид во тоа кој кандидат доминира во кои општини. |
| | 330 | |
| | 331 | {{{ |
| | 332 | CREATE OR REPLACE VIEW public.vw_presidential_by_municipality AS |
| | 333 | WITH cityvotes AS ( |
| | 334 | SELECT e.name AS election_name, r.name AS municipality_name, |
| | 335 | pe.name AS candidate_name, sum(vr.votes) AS total_votes |
| | 336 | FROM vote_result vr |
| | 337 | JOIN election e ON vr.election_id = e.election_id |
| | 338 | JOIN political_entity pe ON vr.entity_id = pe.entity_id |
| | 339 | JOIN polling_station ps ON vr.station_id = ps.station_id |
| | 340 | JOIN region r ON ps.municipality_id = r.region_id |
| | 341 | WHERE e.election_type_id = 1 |
| | 342 | GROUP BY e.name, r.name, pe.name |
| | 343 | ), |
| | 344 | rankedcities AS ( |
| | 345 | SELECT *, rank() OVER (PARTITION BY election_name, municipality_name ORDER BY total_votes DESC) AS pos |
| | 346 | FROM cityvotes |
| | 347 | ) |
| | 348 | SELECT election_name, municipality_name, candidate_name, |
| | 349 | total_votes, 'City Winner'::text AS level |
| | 350 | FROM rankedcities |
| | 351 | WHERE pos = 1; |
| | 352 | }}} |
| | 353 | |
| | 354 | ---- |
| | 355 | |
| | 356 | == vw_regional_voting_patterns |
| | 357 | |
| | 358 | Го прикажува доминантниот политички ентитет по регион за сите типови избори — за претседателски ги агрегира гласовите на државно ниво, а за останатите на општинско ниво. Ја имплементира унифицирана логика за регионална анализа на изборни обрасци применлива на повеќе типови избори истовремено. |
| | 359 | |
| | 360 | {{{ |
| | 361 | CREATE OR REPLACE VIEW public.vw_regional_voting_patterns AS |
| | 362 | WITH regionhierarchy AS ( |
| | 363 | SELECT ps.station_id, |
| | 364 | r.name AS municipality_name, |
| | 365 | parent.name AS sub_region_name, |
| | 366 | grandparent.name AS country_name |
| | 367 | FROM polling_station ps |
| | 368 | JOIN region r ON ps.municipality_id = r.region_id |
| | 369 | LEFT JOIN region parent ON r.parent_region_id = parent.region_id |
| | 370 | LEFT JOIN region grandparent ON parent.parent_region_id = grandparent.region_id |
| | 371 | ), |
| | 372 | candidatevotes AS ( |
| | 373 | SELECT e.election_id, e.name AS election_name, e.election_type_id, |
| | 374 | pe.name AS candidate_name, |
| | 375 | CASE WHEN e.election_type_id = 1 THEN rh.country_name ELSE rh.municipality_name END AS final_region, |
| | 376 | sum(vr.votes) AS total_votes_sum |
| | 377 | FROM vote_result vr |
| | 378 | JOIN election e ON vr.election_id = e.election_id |
| | 379 | JOIN political_entity pe ON vr.entity_id = pe.entity_id |
| | 380 | JOIN regionhierarchy rh ON vr.station_id = rh.station_id |
| | 381 | GROUP BY e.election_id, e.name, e.election_type_id, pe.name, |
| | 382 | CASE WHEN e.election_type_id = 1 THEN rh.country_name ELSE rh.municipality_name END |
| | 383 | ), |
| | 384 | rankedwinners AS ( |
| | 385 | SELECT *, rank() OVER (PARTITION BY election_id, final_region ORDER BY total_votes_sum DESC) AS rnk |
| | 386 | FROM candidatevotes |
| | 387 | ) |
| | 388 | SELECT election_name, final_region AS region_name, |
| | 389 | candidate_name AS dominant_entity, |
| | 390 | total_votes_sum AS winning_votes, |
| | 391 | 'Winner'::text AS status |
| | 392 | FROM rankedwinners |
| | 393 | WHERE rnk = 1 AND final_region IS NOT NULL; |
| | 394 | }}} |
| | 395 | |
| | 396 | ---- |
| | 397 | |
| | 398 | == vw_voter_turnout |
| | 399 | |
| | 400 | Дава сеопфатна статистика за излезност на гласачи по избор и општина — регистрирани гласачи, фрлени ливчиња, валидни, невалидни, процент на излезност и процент на невалидни. Ја имплементира логиката за официјално известување за излезност, задолжително за Државната изборна комисија, со поддршка за `FULL JOIN` за да се прикажат и општини без гласови. |
| | 401 | |
| | 402 | {{{ |
| | 403 | CREATE OR REPLACE VIEW public.vw_voter_turnout AS |
| | 404 | WITH registered AS ( |
| | 405 | SELECT se.election_id, ps.municipality_id AS region_id, |
| | 406 | sum(ps.registered_voter) AS registered_voters |
| | 407 | FROM station_election se JOIN polling_station ps ON ps.station_id = se.station_id |
| | 408 | GROUP BY se.election_id, ps.municipality_id |
| | 409 | ), |
| | 410 | ballots AS ( |
| | 411 | SELECT b.election_id, ps.municipality_id AS region_id, |
| | 412 | count(*) AS ballots_cast, |
| | 413 | count(*) FILTER (WHERE b.is_valid) AS valid_ballots, |
| | 414 | count(*) FILTER (WHERE NOT b.is_valid) AS invalid_ballots |
| | 415 | FROM ballot b JOIN polling_station ps ON ps.station_id = b.station_id |
| | 416 | GROUP BY b.election_id, ps.municipality_id |
| | 417 | ), |
| | 418 | combined AS ( |
| | 419 | SELECT COALESCE(r.election_id, b.election_id) AS election_id, |
| | 420 | COALESCE(r.region_id, b.region_id) AS region_id, |
| | 421 | r.registered_voters, |
| | 422 | b.ballots_cast, b.valid_ballots, b.invalid_ballots, |
| | 423 | b.ballots_cast::numeric * 100.0 / NULLIF(r.registered_voters, 0)::numeric AS turnout_pct_raw, |
| | 424 | b.invalid_ballots::numeric * 100.0 / NULLIF(b.ballots_cast, 0)::numeric AS invalid_pct_raw |
| | 425 | FROM registered r FULL JOIN ballots b ON r.election_id = b.election_id AND r.region_id = b.region_id |
| | 426 | ) |
| | 427 | SELECT e.election_id, e.name AS election_name, e.election_date, |
| | 428 | et.type_name AS election_type, |
| | 429 | c.region_id, rg.name AS region_name, |
| | 430 | COALESCE(c.registered_voters, 0::bigint) AS registered_voters, |
| | 431 | COALESCE(c.ballots_cast, 0::bigint) AS ballots_cast, |
| | 432 | COALESCE(c.valid_ballots, 0::bigint) AS valid_ballots, |
| | 433 | COALESCE(c.invalid_ballots, 0::bigint) AS invalid_ballots, |
| | 434 | round(c.turnout_pct_raw, 2) AS turnout_pct, |
| | 435 | round(c.invalid_pct_raw, 2) AS invalid_pct |
| | 436 | FROM combined c |
| | 437 | JOIN election e USING (election_id) |
| | 438 | JOIN election_type et ON et.election_type_id = e.election_type_id |
| | 439 | JOIN region rg ON rg.region_id = c.region_id |
| | 440 | WHERE c.registered_voters IS NOT NULL OR c.ballots_cast IS NOT NULL |
| | 441 | ORDER BY e.election_date, round(c.turnout_pct_raw, 2) DESC; |
| | 442 | }}} |