fix(analytics): _district_market_saturation latest-snapshot filter (#1221)
domrf_kn_objects/sales_agg хранят ~3 snapshot'а на obj_id (weekly UPSERT, retention=none). JOIN без latest-фильтра считал каждый ЖК N раз: sold_median тянулся старыми perc → sat_factor занижен, гейт n>=5 проходил уже при 2 ЖК (n=6), sat_n завышен ~×N в scope. Сданные ЖК просачивались через старые снапшоты со статусом 'Строящиеся'. Patch: AND a.snapshot_date = (SELECT MAX(snapshot_date) FROM ...) для обеих таблиц (зеркало #1210/#1212). COUNT(*) → COUNT(DISTINCT a.obj_id) defensive. 29 recommend_mix + 8 saturation тестов зелёные. Closes #1221
This commit is contained in:
parent
d694e735cd
commit
780dd5640c
1 changed files with 16 additions and 1 deletions
|
|
@ -1414,12 +1414,21 @@ def _district_market_saturation(db: Session, *, district_name: str) -> tuple[flo
|
|||
|
||||
Возвращает (median_pct, n_objects). None если <5 ЖК с perc.
|
||||
"""
|
||||
# #1221: domrf_kn_objects/domrf_kn_sales_agg хранят ~3 snapshot'а на obj_id
|
||||
# (UNIQUE(obj_id,[type,]snapshot_date), weekly UPSERT, ретенции нет). Без
|
||||
# latest-фильтра один ЖК входил в медиану N раз → sold_median тянется старыми
|
||||
# perc (sold% растёт во времени → sat_factor занижен), гейт n>=5 проходил уже
|
||||
# при 2 ЖК, sat_n завышен ~×N. Фильтруем оба JOIN-партнёра MAX(snapshot_date)
|
||||
# (зеркало #1210/#1212, ср. строки 1200/1208 и latest_obj-CTE стр. ~2780
|
||||
# «иначе comparables дублируются»). COUNT(DISTINCT a.obj_id) — defensive:
|
||||
# после latest-snapshot пары (obj_id, type='apartments') уникальны, но явный
|
||||
# DISTINCT исключает регрессию, если кто-то ослабит UNIQUE-constraint.
|
||||
row = (
|
||||
db.execute(
|
||||
text(
|
||||
"""
|
||||
SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY a.perc) AS sold_median,
|
||||
COUNT(*) AS n
|
||||
COUNT(DISTINCT a.obj_id) AS n
|
||||
FROM domrf_kn_sales_agg a
|
||||
JOIN domrf_kn_objects o
|
||||
ON o.obj_id = a.obj_id
|
||||
|
|
@ -1428,6 +1437,12 @@ def _district_market_saturation(db: Session, *, district_name: str) -> tuple[flo
|
|||
AND a.perc IS NOT NULL
|
||||
AND o.district_name = :dn
|
||||
AND o.site_status = 'Строящиеся'
|
||||
AND a.snapshot_date = (
|
||||
SELECT MAX(snapshot_date) FROM domrf_kn_sales_agg
|
||||
)
|
||||
AND o.snapshot_date = (
|
||||
SELECT MAX(snapshot_date) FROM domrf_kn_objects
|
||||
)
|
||||
"""
|
||||
),
|
||||
{"dn": district_name},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue