gendesign/data/sql/39_territory_aliases.sql
2026-04-27 13:05:36 +03:00

120 lines
7.2 KiB
PL/PgSQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Resolve stat_series.territory ↔ domrf_regions.region_name name mismatches.
-- Stat_series uses Rosstat-style names that differ in 18 of 99 territories:
-- • 9 regions: "г. Москва" vs "Город Москва", "Республика Адыгея (Адыгея)"
-- vs "Республика Адыгея", "- Алания"/"(Татарстан)"/"- Чувашия" suffixes;
-- • 8 federal districts ("Центральный ФО") — not in domrf_regions at all;
-- • 1 synthetic row "Российская Федерация (без г. Москва)";
-- • 2 noise rows '-' and 'г. Москва1' (XLSX parser artefacts).
--
-- Solution: an alias lookup that maps any incoming text to a structured target
-- (level + region_id|fo_id). View v_stat_series_resolved joins observations
-- through it for clean territory resolution without rewriting 809K rows.
BEGIN;
-- ── 1. Federal districts as a first-class table ─────────────────────────────
CREATE TABLE IF NOT EXISTS domrf_federal_districts (
fo_id INT PRIMARY KEY,
fo_name TEXT NOT NULL UNIQUE
);
INSERT INTO domrf_federal_districts (fo_id, fo_name) VALUES
(1, 'Центральный ФО'),
(2, 'Северо-Западный ФО'),
(3, 'Южный ФО'),
(4, 'Северо-Кавказский ФО'),
(5, 'Приволжский ФО'),
(6, 'Уральский ФО'),
(7, 'Сибирский ФО'),
(8, 'Дальневосточный ФО')
ON CONFLICT (fo_id) DO NOTHING;
COMMENT ON TABLE domrf_federal_districts IS
'8 федеральных округов РФ. Связывается с domrf_regions.federal_district по имени, и используется как target для domrf_territory_aliases (level=fo).';
-- ── 2. Generic territory alias table ────────────────────────────────────────
CREATE TABLE IF NOT EXISTS domrf_territory_aliases (
territory_text TEXT PRIMARY KEY,
level TEXT NOT NULL CHECK (level IN ('rf','fo','region','synthetic','noise')),
region_id INT REFERENCES domrf_regions(region_id),
fo_id INT REFERENCES domrf_federal_districts(fo_id),
canonical_name TEXT NOT NULL,
notes TEXT,
CONSTRAINT alias_target_chk CHECK (
(level='rf' AND region_id=0 AND fo_id IS NULL) OR
(level='region' AND region_id IS NOT NULL AND fo_id IS NULL) OR
(level='fo' AND region_id IS NULL AND fo_id IS NOT NULL) OR
(level='synthetic' AND region_id IS NULL AND fo_id IS NULL) OR
(level='noise' AND region_id IS NULL AND fo_id IS NULL)
)
);
CREATE INDEX IF NOT EXISTS idx_territory_aliases_region ON domrf_territory_aliases (region_id);
CREATE INDEX IF NOT EXISTS idx_territory_aliases_fo ON domrf_territory_aliases (fo_id);
COMMENT ON TABLE domrf_territory_aliases IS
'Text→(level, region_id|fo_id) lookup. Resolves stat_series territory naming variants to canonical regions/FO. Use v_stat_series_resolved for joined views.';
-- ── 3a. Auto-populate identity aliases for the 81 regions whose names match ─
-- (and the RF row at region_id=0)
INSERT INTO domrf_territory_aliases (territory_text, level, region_id, canonical_name, notes)
SELECT
r.region_name,
CASE WHEN r.region_id = 0 THEN 'rf' ELSE 'region' END,
r.region_id,
r.region_name,
'auto: identity alias from domrf_regions.region_name'
FROM domrf_regions r
WHERE r.region_name IN (SELECT DISTINCT territory FROM domrf_stat_series_observations)
ON CONFLICT (territory_text) DO NOTHING;
-- ── 3b. Manual aliases for 9 regions with format differences ────────────────
INSERT INTO domrf_territory_aliases (territory_text, level, region_id, canonical_name, notes) VALUES
('г. Москва', 'region', 77, 'Город Москва', 'г./Город prefix mismatch'),
('г. Санкт-Петербург', 'region', 78, 'Город Санкт-Петербург', 'г./Город prefix mismatch'),
('г. Севастополь', 'region', 92, 'Город Севастополь', 'г./Город prefix mismatch'),
('Республика Адыгея (Адыгея)', 'region', 1, 'Республика Адыгея', 'parenthetical suffix in Rosstat naming'),
('Республика Татарстан (Татарстан)', 'region', 16, 'Республика Татарстан', 'parenthetical suffix in Rosstat naming'),
('Республика Северная Осетия - Алания', 'region', 15, 'Республика Северная Осетия', '- Алания suffix in Rosstat naming'),
('Чувашская Республика - Чувашия', 'region', 21, 'Чувашская Республика', '- Чувашия suffix in Rosstat naming')
ON CONFLICT (territory_text) DO NOTHING;
-- Note: "Республика Саха (Якутия)" and "Кемеровская область - Кузбасс" use the
-- same parenthetical convention BUT match exactly between sources, so identity
-- aliases above already cover them.
-- ── 3c. Federal districts — 8 aliases pointing at the new FO table ──────────
INSERT INTO domrf_territory_aliases (territory_text, level, fo_id, canonical_name, notes)
SELECT fo_name, 'fo', fo_id, fo_name, 'auto: identity alias from domrf_federal_districts'
FROM domrf_federal_districts
ON CONFLICT (territory_text) DO NOTHING;
-- ── 3d. Synthetic + noise rows ──────────────────────────────────────────────
INSERT INTO domrf_territory_aliases (territory_text, level, canonical_name, notes) VALUES
('Российская Федерация (без г. Москва)', 'synthetic', 'РФ без Москвы',
'Synthetic row in some XLSX summaries — RF totals excluding Moscow.'),
('-', 'noise', '-', 'XLSX parser artefact: empty separator row swallowed by parser.'),
('г. Москва1', 'noise', 'г. Москва1','XLSX source typo (extra "1" suffix). Real "г. Москва" present separately.')
ON CONFLICT (territory_text) DO NOTHING;
-- ── 4. Resolved view: stat_series_observations + alias target ───────────────
CREATE OR REPLACE VIEW v_stat_series_resolved AS
SELECT
o.snapshot_date,
o.file_name,
o.sheet_code,
i.indicator_name,
o.territory,
a.level AS territory_level,
a.region_id,
a.fo_id,
a.canonical_name,
o.obs_date,
o.value
FROM domrf_stat_series_observations o
LEFT JOIN domrf_territory_aliases a
ON a.territory_text = o.territory
LEFT JOIN domrf_stat_series_indicators i
ON i.file_name = o.file_name AND i.sheet_code = o.sheet_code;
COMMENT ON VIEW v_stat_series_resolved IS
'stat_series_observations + indicator name + resolved territory (level/region_id/fo_id). Filter WHERE territory_level=''region'' for clean region-level analysis.';
COMMIT;