47 lines
2 KiB
SQL
47 lines
2 KiB
SQL
-- audit_address_sample.sql
|
|
-- Random sample of EKB houses for the address-mismatch audit (issue #582).
|
|
--
|
|
-- Strategy:
|
|
-- 1. Filter to houses with non-null lat/lon and non-empty address.
|
|
-- 2. Random shuffle via `ORDER BY random()` — repeatable enough for spot
|
|
-- sampling without needing a stable PRNG seed (the audit table dedupes
|
|
-- via UNIQUE (house_id, audit_batch), so re-running gives idempotent
|
|
-- results regardless of which rows land in the sample first).
|
|
-- 3. Cap the result at :limit_per_district * 8 rows — keeps the bind-param
|
|
-- contract compatible with the old stratified sampler (`:limit_per_district`
|
|
-- is still honored, just multiplied by the assumed 8-district count).
|
|
--
|
|
-- Why no spatial stratification anymore:
|
|
-- The previous version JOINed to `gendesign_ekb_districts_geom` (FDW
|
|
-- polygon table) to bucket houses by admin district. That join is fine on
|
|
-- prod where FDW is wired, but it adds a dependency we don't need for
|
|
-- Phase 2-3 (backfill + canonical reverse). Aggregation by district at
|
|
-- report time still works — we re-derive district during the audit via
|
|
-- spatial containment in the report SQL when needed.
|
|
--
|
|
-- Bind param:
|
|
-- :limit_per_district — kept for back-compat with the audit driver.
|
|
-- Effective sample size = :limit_per_district * 8 (e.g. 25 → 200).
|
|
--
|
|
-- Columns returned:
|
|
-- id, address, lat, lon, district
|
|
-- `district` is always NULL here — the audit driver will reverse-derive it
|
|
-- from Yandex Geocoder response (Yandex returns admin component) or leave
|
|
-- it NULL if not present in the response.
|
|
--
|
|
-- NB: uses CAST(:x AS int) per project sql.md rule (psycopg v3 ignores ::type
|
|
-- after bind params).
|
|
|
|
SELECT
|
|
h.id,
|
|
h.address,
|
|
h.lat,
|
|
h.lon,
|
|
NULL::text AS district
|
|
FROM houses h
|
|
WHERE h.lat IS NOT NULL
|
|
AND h.lon IS NOT NULL
|
|
AND h.address IS NOT NULL
|
|
AND length(trim(h.address)) > 0
|
|
ORDER BY random()
|
|
LIMIT CAST(:limit_per_district AS int) * 8;
|