basedosdados / basedosdados/pipelines
[databug] br_ms_sih: competência 2024-08 duplicada (aihs_reduzidas e servicos_profissionais); SP ~2x também em 2024-01/02
- Dominant language
- Python
- Stars
- 49
- Forks
- 22
- Avg merge
- 19h 31m
- Merged PRs (30d)
- 165
Description
### Tabela afetada
`br_ms_sih.aihs_reduzidas` e `br_ms_sih.servicos_profissionais`
### Descrição do problema nos dados
A **competência 2024-08 está carregada em dobro nas duas tabelas**: todas as linhas do mês aparecem exatamente 2 vezes, byte a byte idênticas. Na `aihs_reduzidas`, todos os 1.142.359 grupos de linhas idênticas têm contagem exatamente 2 (mín=2, máx=2, zero grupos ímpares) — assinatura de carga dupla do mês inteiro. Varri 2024-01 a 2025-10: nos demais meses a tabela não tem nenhuma duplicata de linha inteira.
Além disso, a `servicos_profissionais` apresenta o mesmo problema em **2024-01 e 2024-02**, de forma imperfeita: quase todas as linhas aparecem 2x, mas há centenas de milhares de linhas singleton — padrão compatível com a concatenação de **duas versões ligeiramente diferentes** do mesmo mês (ex.: carga original + reprocessamento).
Impacto: qualquer análise agregada sobre esses meses sai dobrada — ex.: `SUM(valor_aih)` de 2024-08 dá **R$ 4,07 bi** quando o real é **R$ 2,03 bi**. É silencioso: os registros duplicados são individualmente válidos (sem NULLs ou zeros que denunciem).
**`aihs_reduzidas`, 2024-08 vs vizinhos:**
| Mês | Linhas | Linhas inteiras distintas | Razão | SUM(valor_aih) |
|---|---|---|---|---|
| 2024-07 | 1.130.156 | 1.130.156 | 1,000 | R$ 1,98 bi |
| **2024-08** | **2.284.718** | **1.142.359** | **2,000** | **R$ 4,07 bi** |
| 2024-09 | 1.117.171 | 1.117.171 | 1,000 | R$ 1,99 bi |
**`servicos_profissionais`, três meses anômalos:**
| Mês | Linhas | Linhas distintas | Grupos ímpares | Razão |
|---|---|---|---|---|
| **2024-01** | **29.930.666** | 14.620.720 | 475.424 | **2,047** |
| **2024-02** | **29.109.021** | 14.494.462 | 1.016.789 | **2,008** |
| 2024-07 (normal) | 15.883.735 | 15.254.602 | ~15,0M | 1,041 |
| **2024-08** | **32.303.966** | 15.483.216 | **0** | **2,086** |
Obs.: num mês normal a SP tem ~4% de linhas idênticas legítimas (atos repetidos da mesma AIH), então `SELECT DISTINCT` não é uma correção segura para essa tabela — o caminho provável é recarregar 2024-08 (carga única) nas duas tabelas e, para SP 2024-01/02, verificar no pipeline a dupla ingestão de versões diferentes do mês.
### Evidência
```sql
SELECT ano, mes,
COUNT(*) AS n_linhas,
COUNT(DISTINCT TO_JSON_STRING(t)) AS linhas_distintas
FROM `basedosdados.br_ms_sih.aihs_reduzidas` t
WHERE ano = 2024 AND mes BETWEEN 7 AND 9
GROUP BY ano, mes ORDER BY mes;
-- 2024-07: 1130156 | 1130156
-- 2024-08: 2284718 | 1142359 <- exatamente 2x
-- 2024-09: 1117171 | 1117171
```
```sql
-- assinatura de carga dupla: todo grupo de linhas idênticas com contagem PAR
SELECT COUNT(*) AS grupos, COUNTIF(MOD(c, 2) = 1) AS grupos_impares, MIN(c) AS min_c, MAX(c) AS max_c
FROM (
SELECT TO_JSON_STRING(t) AS j, COUNT(*) AS c
FROM `basedosdados.br_ms_sih.aihs_reduzidas` t
WHERE ano = 2024 AND mes = 8
GROUP BY j
);
-- grupos=1142359 | grupos_impares=0 | min_c=2 | max_c=2
```
```sql
-- SP: mesma varredura por mês (razão ~2 em 2024-01, 2024-02 e 2024-08)
SELECT ano, mes, SUM(c) AS n_linhas, COUNT(*) AS linhas_distintas,
COUNTIF(MOD(c, 2) = 1) AS grupos_impares, ROUND(SUM(c) / COUNT(*), 3) AS razao
FROM (
SELECT ano, mes, TO_JSON_STRING(t) AS j, COUNT(*) AS c
FROM `basedosdados.br_ms_sih.servicos_profissionais` t
WHERE ano = 2024
GROUP BY ano, mes, j
)
GROUP BY ano, mes ORDER BY ano, mes;
```
Verificação feita em 2026-07-06, diretamente no BigQuery. Propriedade útil para validar a correção: nos meses normais de 2024, `SUM(valor_ato_profissional)` da SP bate **ao centavo** com `SUM(valor_aih)` da RD na mesma competência.
### Referências
- Fonte original: [Produção Hospitalar (SIH/SUS) – DATASUS](https://datasus.saude.gov.br/acesso-a-informacao/producao-hospitalar-sih-sus/)
- Dataset na BD: https://basedosdados.org/dataset/ff933265-8b61-4458-877a-173b3f38102b
- Defeito independente nas mesmas tabelas (linhas com `id_aih` vazio em 2024-03/04), reportado em issue separada: https://github.com/basedosdados/pipelines/issues/1634
Sou consumidor do dataset e fico à disposição para verificações adicionais que ajudem na correção.
Contributor guide
Research direction
Start by tracing the ingestion flow that populates br_ms_sih.aihs_reduzidas and br_ms_sih.servicos_profissionais, then rerun the SQL checks in the issue against BigQuery. Verify the 2024-08 duplicate load in both tables and investigate the differing duplicate versions in servicos_profissionais for 2024-01/02. Done means the affected months are corrected and the stated aggregate comparisons validate the result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sql
- Domain
- data-engineering, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100