GIAS ships the whole UK plus overseas and offshore establishments. None of
them carry comparable DfE performance data — Wales does not publish on the
English measures at all — so every one of these pages rendered with null
results, null Ofsted and null phase. There were 2,036 of them: 1,569 Welsh,
123 offshore (Jersey, Guernsey, Isle of Man, Gibraltar), 316 British schools
overseas and 28 service children's schools. All 2,036 were being submitted to
search engines, alongside 29 local authorities that existed in the filters
purely to list them.
Filter at the mart boundary rather than the view layer. dim_school and
dim_location both exclude TypeOfEstablishment in {25, 26, 30, 37}, listed once
as vars.non_england_school_type_codes. Everything downstream reads those two
marts — search, the school page, /api/filters, rankings, Typesense and
build_sitemap() — so one filter removes them from the site and the sitemap
together, and Typesense drops them on its next rebuild since it recreates the
collection and swaps the alias rather than upserting in place.
coalesce rather than a bare NOT IN: a null type code would make the predicate
null and drop the row silently, and an unknown type is not grounds for
exclusion. No establishment has a null type today, but a future GIAS refresh
could ship one and the loss would be invisible.
assert_england_only_schools guards both directions: no excluded type survives
in dim_school, and dim_location holds no URN dim_school lacks — the API
inner-joins them, so the two filters drifting apart would silently shrink the
corpus.
Corpus goes from 27,229 schools to 25,193, and the authority list from 182 to
153. The 1,569 Welsh URLs now 404.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
40 lines
1.6 KiB
SQL
40 lines
1.6 KiB
SQL
-- Mart: School location dimension — one row per URN, PostGIS-enabled
|
|
-- Geometry derived from GIAS easting/northing (British National Grid → WGS84).
|
|
-- For schools missing easting/northing, the geocode script backfills via Postcodes.io.
|
|
|
|
select
|
|
s.urn,
|
|
s.address_line1,
|
|
s.address_line2,
|
|
s.town,
|
|
s.county,
|
|
s.postcode,
|
|
s.local_authority_code,
|
|
s.local_authority_name,
|
|
s.parliamentary_constituency,
|
|
s.urban_rural,
|
|
s.easting,
|
|
s.northing,
|
|
case
|
|
when s.easting is not null and s.northing is not null
|
|
then ST_Transform(ST_SetSRID(ST_MakePoint(s.easting::double precision, s.northing::double precision), 27700), 4326)
|
|
else null
|
|
end as geom,
|
|
case
|
|
when s.easting is not null and s.northing is not null
|
|
then ST_Y(ST_Transform(ST_SetSRID(ST_MakePoint(s.easting::double precision, s.northing::double precision), 27700), 4326))
|
|
else null
|
|
end as latitude,
|
|
case
|
|
when s.easting is not null and s.northing is not null
|
|
then ST_X(ST_Transform(ST_SetSRID(ST_MakePoint(s.easting::double precision, s.northing::double precision), 27700), 4326))
|
|
else null
|
|
end as longitude
|
|
from {{ ref('stg_gias_establishments') }} s
|
|
-- Must match dim_school's status and England filters exactly (the API
|
|
-- inner-joins the two).
|
|
where s.status_code in (1, 3)
|
|
-- coalesce, not a bare NOT IN: a null type code would make the predicate
|
|
-- null and drop the row silently. Unknown type is not grounds for exclusion.
|
|
and coalesce(s.school_type_code, -1) not in ({{ var('non_england_school_type_codes') | join(', ') }})
|