Pixelmancer
Django banner, white text in green background

Written by - Hugo Billé Martins

SQL é muito legal

Eu amo SQL. Além de ser interessantísimo criar a estrutura do seu banco de dados (de forma inteligente), principalmente com a assistência de uma ORM, elaborar e executar querys no SQL também é algo que tenho paixão especial.

Trabalhar com banco de dados é sempre uma mistura de estruturar o banco o mais rápido possível para que o processo de desenvolvimento comece logo mas também é um trabalho de paciência e planejamento; pensar em problemas futuros é a forma ideal de evitar dores de cabeça. O mesmo vale para as querys, você pode acabar com uma solução rápida e prática mas nem sempre é a sulução ideal, e as vezes a demanda para resolver um problema pode levar a resultados incoerentes que, aos olhos distraídos, podem parecer corretos.

Todo o comando no sql é executado com um propósito, é um problema esperando para ser resolvido. Mesmo sendo ótimo "resolver" um problema rapidamente, o objetivo primário em resolver um problema é... resolve-lo corretamente.

Enfim, chega de falar sobre como temos que tomar cuidado a executar querys no SQL e interpretar corretamente dados. O objetivo principal com essa postagem é contar sobre minhas aventurar no meu estágio, e registrar como resolvi os problemas envolvendo SQL e de quebra guardar esses comandos em um lugar permanente, porque alguns são extremamente úteis em situações diversas.

Escola de engermagem

A estrutura do banco de dados pode ser encontrada no §github, pretendo fazer a diagramação dela quando a sua estrutura já estiver mais desenvolvida.

Contexto

O comando em questão foi executado para gerar a lista dos candidatos que passaram em um concurso público de uma escola de enfermagem. O edital que estruturou esse concurso possuia algumas condições:

  1. Serão ofertadas vagas padrão e vagas reservadas para aqueles que se incluem em um ou mais dos seguintes grupos:
  • Pessoa com deficiência
  • utodeclarado negro, pardo ou indígena
  • renda bruta mensal igual ou inferior a 1,5 salário mínimo per capita
  • cursou o ensino fundamental integralmente em escola pública
  • cursou o ensino médio integralmente em escola pública
  1. Caso a pessoa desejar concorrer à vagas reservadas, ela passará a concorrer somente pelas vagas reservadas
  2. A nota da prova é o fator primário de colocação do candidato
  3. Em caso de empate entre dois ou mais candidatos concorrendo à vagas reservadas, o primeiro critério de desempate será sua "pontuação", de acordo com a quantidade de grupos em que se encaixa, por exemplo:
  • Se o candidato for uma pessoa com deficiência, ela receberá um ponto.
  • Se o candidato cursou o ensino médio e o ensino fundamental em escola pública, ele receberá dois pontos.
  • E assim por diante...
  1. Se um empate ocorrer entre candidatos das vagas não reservadas ou se ocorreu empate entre candidatos com a mesma nota e pontuação, o último critério de desempate será a idade dos candidatos.

O comando e desafios

Temos alguns desafios para serem enfrentados, vamos separa-los em partes:

  1. descobrir o nome, nota obtida, idade e a pontuação de cada candidato
  2. calcular a pontuação do candidato
  3. ordernar o resultado de 3 formas diferentes:
  4. Por nota
  5. Caso primeiro empate, decidir por pontuação
  6. Caso novo empate, decidir por idade, prioritarizando os mais novos
enfermagem_resultados.sql
Copy

_13
_13
select selecao_candidato.id, nome, nota,
_13
floor((LENGTH(concat(deficiencia, ensino_fundamental_publico, ensino_medio_publico, renda_bruta, autodeclaracao))
_13
- LENGTH(REPLACE(concat(deficiencia, ensino_fundamental_publico, ensino_medio_publico, renda_bruta, autodeclaracao), 'S', '')))/LENGTH('S'))
_13
as pontuação,
_13
TIMESTAMPDIFF(YEAR, dt_nascimento, CURDATE()) as idade,
_13
dt_nascimento
_13
from selecao_candidato
_13
left join selecao_nota on (selecao_candidato.id = selecao_nota.candidato_id)
_13
where floor((LENGTH(concat(deficiencia, ensino_fundamental_publico, ensino_medio_publico, renda_bruta, autodeclaracao))
_13
- LENGTH(REPLACE(concat(deficiencia, ensino_fundamental_publico, ensino_medio_publico, renda_bruta, autodeclaracao), 'S', '')))/LENGTH('S')) = 0
_13
group by selecao_candidato.id
_13
order by nota desc, pontuação desc, idade;

COVID

consolidação.sql
Copy

_36
_36
WITH latest_dt_ocorrencia AS (
_36
SELECT paciente_id, MAX(dt_notificacao) AS latest_dt
_36
FROM casos_ocorrencia
_36
GROUP BY paciente_id
_36
), latest_dt_acompanhamento AS (
_36
SELECT ocorrencia_id, MAX(dt_inclusao) AS latest_dt
_36
FROM casos_acompanhamento
_36
GROUP BY ocorrencia_id
_36
)
_36
SELECT DISTINCT
_36
bairro_id,
_36
sexo,
_36
(SELECT casos_faixa_etaria.id FROM casos_faixa_etaria WHERE
_36
(SELECT
_36
YEAR(from_days(DATEDIFF(casos_paciente.dt_inclusao, dt_nascimento))) -
_36
CASE
_36
WHEN CAST(casos_paciente.dt_inclusao AS DATE) < CAST(dt_nascimento AS DATE) + INTERVAL '1' year THEN 1
_36
ELSE 0
_36
END) BETWEEN idade_inicio AND idade_fim) as faixa_etaria_id,
_36
evolucao,
_36
classificacao,
_36
CASE
_36
WHEN casos_internacao.id IS NOT NULL THEN 1
_36
ELSE 0
_36
END AS internado,
_36
profissional_saude,
_36
COUNT(DISTINCT casos_ocorrencia.id) as quantidade
_36
FROM casos_ocorrencia
_36
JOIN latest_dt_ocorrencia on casos_ocorrencia.paciente_id = latest_dt_ocorrencia.paciente_id and casos_ocorrencia.dt_notificacao = latest_dt_ocorrencia.latest_dt
_36
_36
JOIN casos_acompanhamento on casos_ocorrencia.id = casos_acompanhamento.ocorrencia_id
_36
join latest_dt_acompanhamento on casos_acompanhamento.ocorrencia_id = latest_dt_acompanhamento.ocorrencia_id and casos_acompanhamento.dt_inclusao = latest_dt_acompanhamento.latest_dt
_36
JOIN casos_paciente on casos_ocorrencia.paciente_id = casos_paciente.id
_36
LEFT JOIN casos_internacao on casos_internacao.paciente_id = casos_paciente.id
_36
GROUP BY bairro_id, sexo, faixa_etaria_id, evolucao, classificacao, internado;