Resultados: simplificación de la query de Cargo/Abono (v0.3)
Contexto y encargo original: contexto_v03_simplificar.md.
Query ganadora: queries/gastos/cargo_abono_folio_v03_simplificada.sql.
Script de iteración (reproducible): queries/gastos/_iterar_v03.py.
Punto de partida
Query actual (árbol recursivo sobre Grupo_Cuenta_Contable + CASE de 4 niveles
para Abono), corrida tal cual contra v01_baseline_enero2026_sin_nomina_consumo.csv:
- 99.7% de reconciliación (1421/1425 folios) — confirma el número documentado.
- Los 4 folios que fallan son exactamente los ya conocidos:
0001-0034998,0001-0034999,0005-0181359(reversiones contables) y0005-0177136(GASTO_RECLASIFICACION).
Iteración: 8 variantes probadas
Cada variante mide (CARGO - ABONO) - IMPORTE contra el mismo baseline; se
considera reconciliado si la diferencia es < $1.
| Variante | Qué le quita al baseline | Joins extra | % reconcilia |
|---|---|---|---|
| V0 — baseline actual | — | Cuenta_Contable + CTE recursivo | 99.7% (1421/1425) |
V1 — Cc_Grupo_Cuenta_Contable directo | árbol recursivo | Cuenta_Contable | 99.4% (1417/1425) |
V2 — cuenta='6' + fallback descripción | árbol + chequeo de grupo | Cuenta_Contable | 99.6% (1420/1425) |
V3 — solo LEFT(cuenta,1)='6' | árbol + join a Cuenta_Contable + 3 de 4 ramas del CASE | ninguno | 99.6% (1419/1425) |
| V4 — solo Cargo, sin Abono | todo lo de Abono | ninguno | 99.4% (1417/1425) |
| V5 — Cargo − todo el Abono sin filtrar | el filtro de cuenta (control) | ninguno | 90.6% (1291/1425) |
| V6 — árbol recursivo, solo raíz=‘F’ | 2 de 4 ramas del CASE (mantiene árbol) | Cuenta_Contable + CTE | 99.6% (1420/1425) |
| V7 — cuenta ∈ (‘5’,‘6’) | igual que V3 pero rango más amplio | ninguno | 99.6% (1419/1425) |
Hallazgo clave: casi toda la reconciliación viene de la parte de Cargo; el
Abono con lógica de árbol completo (V0) solo rescata 4 folios más que quitarlo
del todo (V4), y solo 2 folios más que quedarse con una única condición sobre
Cc_Cve_Cuenta_Contable que ya vive en Poliza_Detalle (V3, sin joins extra).
Variante ganadora: V3
SUM(CASE WHEN Pd_Tipo=2 AND LEFT(Cc_Cve_Cuenta_Contable,1)='6' THEN Pd_Importe ELSE 0 END)
- 99.6% (1419/1425), solo 0.1pp por debajo del baseline de 99.7%.
- Sin CTE recursivo, sin join a
Cuenta_Contableni aGrupo_Cuenta_Contable: la única condición de Abono usa una columna que ya está enPoliza_Detalle. - Comparada con V4 (quitar Abono del todo, misma cantidad de joins: cero extra), la condición de cuenta=‘6’ es prácticamente gratis en complejidad y recupera 2 folios más — no hay razón para preferir V4.
- Se descartó buscar más allá de 99.6% (V0/V2/V6 llegan a 99.6–99.7%) porque
eso exige reintroducir el árbol recursivo y/o el join a
Cuenta_Contableque esta simplificación existe para evitar; el piso pedido era 80%.
Folios que no reconcilian con V3 (6 de 1425, 0.4%) — los mismos 4 ya documentados más 2 nuevos, ambos de causa conocida (Abono real que cae en el fallback de descripción o en una rama del árbol que no resuelve a raíz ‘F’ pero tampoco tiene prefijo de cuenta ‘6’):
0001-0034998, 0001-0034999, 0005-0181359 -- reversiones (Importe <= -$1)
0005-0177136 -- GASTO_RECLASIFICACION
0005-0176654, 0007-0082476 -- Abono fuera de cuenta '6' (nuevos)
Benchmark de velocidad (5 corridas c/u, incluye ida y vuelta a la BD)
| Variante | Min (s) | Prom (s) |
|---|---|---|
| V0 — baseline actual | 0.636 | 0.745 |
| V3 — ganadora | 0.147 | 0.156 |
| V4 — solo Cargo | 0.150 | 0.159 |
| V5 — Cargo−Abono sin filtrar | 0.137 | 0.165 |
V3, V4 y V5 comparten el mismo grafo de joins (ninguno extra sobre la cadena
base Gasto_Registro → Poliza_Control → Poliza → Poliza_Detalle), así que su
tiempo es esencialmente el mismo (~0.15s); las diferencias entre ellas están
dentro del ruido de red/servidor. V0 es 4-5x más lenta por el CTE
recursivo sobre Grupo_Cuenta_Contable y el join extra a Cuenta_Contable.
V5 es marginalmente la más rápida pero solo reconcilia 90.6% — no vale la pena sacrificar ~9 puntos de reconciliación por ~10-15 milisegundos.
Bugs evitados (no reintroducidos)
Los 4 bugs documentados en contexto_v03_simplificar.md (colisión de
Gr_Folio entre sucursales, colisión de Pd_Referencia entre años,
comparación contra TOTAL con IVA en vez de SUBTOTAL, filtro de empresa vía
Sucursal.Em_Cve_Empresa) se mantienen intactos en V3: la cadena de joins
(Poliza_Control por Pc_Documento, Poliza_Detalle por Pd_Referencia
acotado por Pl_Folio) es idéntica a la del baseline; solo cambió la
condición de Abono.
Alcance
Todo a nivel folio — no se implementó atribución por documento
(Gasto_Registro_Control), fuera del alcance de esta tarea.