feat(destinations): staging models that keep 'withheld' distinct from 'absent'
safe_numeric maps every EES sentinel to NULL, which is right for attainment and wrong here: one of those states has to print 'withheld' and the other has to print nothing. A status column carries the difference. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvdDKvFFSZuMVDH5fEyTob
This commit is contained in:
1 parent
9188626051
commit
c564566432
3 files changed
+107
No files matched your search
@@ -33,6 +33,20 @@ sources:
|
||||
- name: legacy_ks2
|
||||
description: Pre-COVID KS2 school-level data (2015-16 to 2018-19) from DfE performance tables
|
||||
|
||||
- name: ees_ks4_destinations
|
||||
description: >
|
||||
KS4 leavers destinations, long format — one row per URN x year x
|
||||
pupil group x destination measure, plus England rows with a null urn.
|
||||
pupils_raw and percentage_raw are TEXT and may carry the 'c'
|
||||
suppression sentinel; they must never be passed through safe_numeric,
|
||||
because the categories sum to the cohort and collapsing 'c' to null
|
||||
lets a downstream sum recover a withheld figure.
|
||||
|
||||
- name: ees_ks5_destinations
|
||||
description: >
|
||||
16-18 study leavers destinations. Same grain, same suppression
|
||||
caveat, and only institutions with post-16 provision appear.
|
||||
|
||||
- name: ees_ks4_performance
|
||||
description: KS4 performance tables (long format — one row per school × breakdown × sex)
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{{ config(materialized='table') }}
|
||||
|
||||
-- Staging model: KS4 leavers destinations, school level plus the England
|
||||
-- reference (which carries a null urn).
|
||||
--
|
||||
-- DELIBERATELY DOES NOT USE safe_numeric. That macro maps every EES sentinel
|
||||
-- (z, c, x, q, u) to NULL, which is right for attainment — there, "suppressed"
|
||||
-- and "not applicable" are equally unrenderable. Here they are different
|
||||
-- claims: one has to print "withheld", the other has to print nothing, and
|
||||
-- collapsing them would also let a downstream sum reconstruct a withheld
|
||||
-- figure, because the destination categories add up to the cohort.
|
||||
--
|
||||
-- See docs/superpowers/specs/2026-08-28-destination-measures-design.md.
|
||||
|
||||
with source as (
|
||||
select * from {{ source('raw', 'ees_ks4_destinations') }}
|
||||
-- National rows carry a null urn and feed fact_destination_national.
|
||||
where (urn is null or urn = '' or urn ~ '^[0-9]+$')
|
||||
and time_period ~ '^[0-9]+$'
|
||||
)
|
||||
|
||||
select
|
||||
case when urn ~ '^[0-9]+$' then cast(trim(urn) as integer) end as urn,
|
||||
cast(trim(time_period) as integer) as year,
|
||||
trim(pupil_group) as pupil_group,
|
||||
trim(destination_measure) as destination_measure,
|
||||
|
||||
case when cohort_pupils ~ '^[0-9]+$'
|
||||
then cast(cohort_pupils as integer) end as cohort_pupils,
|
||||
|
||||
case when pupils_raw ~ '^[0-9]+$'
|
||||
then cast(pupils_raw as integer) end as pupils,
|
||||
|
||||
case when percentage_raw ~ '^-?[0-9]+(\.[0-9]+)?$'
|
||||
then cast(percentage_raw as numeric) end as percentage,
|
||||
|
||||
-- The whole point of this model. 'suppressed' is DfE withholding a figure
|
||||
-- it considers disclosive; 'not_applicable' is the measure not applying to
|
||||
-- this row at all. The API and the frontend treat them differently.
|
||||
case
|
||||
when pupils_raw ~ '^[0-9]+$' then 'published'
|
||||
when lower(trim(pupils_raw)) = 'c' then 'suppressed'
|
||||
else 'not_applicable'
|
||||
end as status
|
||||
|
||||
from source
|
||||
@@ -0,0 +1,47 @@
|
||||
{{ config(materialized='table') }}
|
||||
|
||||
-- Staging model: 16-18 study leavers destinations, institution level plus the
|
||||
-- England reference (which carries a null urn). Only sixth forms and colleges
|
||||
-- appear here, so a secondary with no post-16 provision has no rows at all.
|
||||
--
|
||||
-- DELIBERATELY DOES NOT USE safe_numeric. That macro maps every EES sentinel
|
||||
-- (z, c, x, q, u) to NULL, which is right for attainment — there, "suppressed"
|
||||
-- and "not applicable" are equally unrenderable. Here they are different
|
||||
-- claims: one has to print "withheld", the other has to print nothing, and
|
||||
-- collapsing them would also let a downstream sum reconstruct a withheld
|
||||
-- figure, because the destination categories add up to the cohort.
|
||||
--
|
||||
-- See docs/superpowers/specs/2026-08-28-destination-measures-design.md.
|
||||
|
||||
with source as (
|
||||
select * from {{ source('raw', 'ees_ks5_destinations') }}
|
||||
-- National rows carry a null urn and feed fact_destination_national.
|
||||
where (urn is null or urn = '' or urn ~ '^[0-9]+$')
|
||||
and time_period ~ '^[0-9]+$'
|
||||
)
|
||||
|
||||
select
|
||||
case when urn ~ '^[0-9]+$' then cast(trim(urn) as integer) end as urn,
|
||||
cast(trim(time_period) as integer) as year,
|
||||
trim(pupil_group) as pupil_group,
|
||||
trim(destination_measure) as destination_measure,
|
||||
|
||||
case when cohort_pupils ~ '^[0-9]+$'
|
||||
then cast(cohort_pupils as integer) end as cohort_pupils,
|
||||
|
||||
case when pupils_raw ~ '^[0-9]+$'
|
||||
then cast(pupils_raw as integer) end as pupils,
|
||||
|
||||
case when percentage_raw ~ '^-?[0-9]+(\.[0-9]+)?$'
|
||||
then cast(percentage_raw as numeric) end as percentage,
|
||||
|
||||
-- The whole point of this model. 'suppressed' is DfE withholding a figure
|
||||
-- it considers disclosive; 'not_applicable' is the measure not applying to
|
||||
-- this row at all. The API and the frontend treat them differently.
|
||||
case
|
||||
when pupils_raw ~ '^[0-9]+$' then 'published'
|
||||
when lower(trim(pupils_raw)) = 'c' then 'suppressed'
|
||||
else 'not_applicable'
|
||||
end as status
|
||||
|
||||
from source
|
||||
Reference in new issue
Block a user