Calcular a quantidade de clientes por idade

Boa noite.
Queria uma ajuda de vocês para criar um método java que calculasse a quantidade de clientes cadastrados no meu banco por idade, ex:

idade | quantidade
7 … 0
18…10

A minha classe Cliente, tem o atributo dtNasc .
Não sei se meu raciocínio está certo, mas entendo que tenho que pegar a quantidade cadastrada no banco, depois pegar a data de nascimento de cada cliente e calcular a idade e por fim contar quantos com idade de 7 a 99 anos.

No meu Dao, estava tentando fazer assim:

public List<String> getQtdClientePorIdade( )  {
        ArrayList<String> listPorIdade = new ArrayList<>();
            Criteria crit = this.getSession().createCriteria(Cliente.class)
                    .setProjection(Projections.rowCount())
                    .add(Restrictions.eq("status", "Ativo"));            
           
            Long qtdClienteAtivo = (Long) crit.uniqueResult();
            if (qtdClienteAtivo == null) {
                qtdClienteAtivo = 0L;
            }

            for (int i = 0; i <= qtdClienteAtivo; i++) {  // Aqui pegaria a quantidade de clientes no banco
            
        }
            for (int i = 7; i <= 99; i++) {    // Aqui faria o calculo de quantos clientes por idade de 7 a 99 anos
            
            listPorIdade.add(s);
            
        }
        return listPorIdade;
    }

Não sei se esse laço está correto e como eu poderia calcular a idade pela data de nascimento no momento que cada cliente fosse pego.
Teriam como me ajudar nisso?
Grato

Olá,
poupe trabalho redundante, este agrupamento por idade que vc quer deve ser feito pela consulta no banco, usando GROUP BY.

@Rodrigo_Void e como eu faria atraves do hibernate, esta consulta:

SELECT COUNT(*) FROM tb_pessoa WHERE EXTRACT(YEAR FROM dt_nasc) = 1990;

Ela retorna exatamente oque preciso. Só não sei como faze-la usando criteria do hibernate.

@gtalkSP, para adequar isso a utilização de criteria, você precisa olhar do ponto de vista dos objetos da tua aplicação.
Vamos supor que você tenha uma classe chamada Pessoa que está representando a tabela tb_pessoa. Esta classe possui um atributo chamado dtNasc que representa a coluna dt_nasc.
Assim sendo, tua criteria seria algo como

Criteria criteria = session.createCriteria(Pessoa.class);
criteria.add(Restrictions.eq("dtNasc", 1990);
criteria.setProjection(Projections.rowCount());
Number number = (Number) criteria.uniqueResult();

O código acima, obviamente, não funciona, afinal, o tipo de dado representado pelo atributo dtNasc é um Date (ou similar). Logo, passar um número (1990) não resolve.
Logo, você terá que criar um objeto de Date com o valor correspondente e, mesmo assim, correr o risco de ter 365 clientes nascidos em cada um dos dias do ano de 1990 (ou qualquer outro ano. Se o ano é bissexto, pode ter 366 chances).
Assim, o que eu acho mais adequado seria fazer um select para obter os anos de nascimento (dentro ou não de um intervalo pré definido) e, a partir daí, calcular quantos clientes tem essa ou aquela idade.
Na verdade, talvez seja possível fazer o cálculo enquanto faz o select e já devolver a idade e a quantidade de pessoas que se encaixam nela.
Ponto de discordância: se você quiser mais precisão, vai necessitar calcular as idades com base em dia, mês e ano, afinal, se estamos no mês de março, quem nasceu em 10/02/1990 não tem a mesma idade de quem nasceu em 10/05/1990, não é mesmo? Você receberá dados falsos se for tão simplista assim.
Existem opções para estes cálculos, vai de você ir atrás e conseguir adaptar à tua necessidade.

1 curtida

Uma opção é você realizar o select bruto e tratar isso no java.
Se meu tempo fosse curto, eu optaria por essa abordagem.

//Código necessário aqui
stm = con.prepareStatement("SELECT col1, col2, coln, dt_nasc FROM tb_pessoa ORDER BY dt_nasc");
ResultSet rs = stm.executeQuery();
Map<Integer, Integer> clientesPorIdade = new HashMap<Integer, Integer>();
while(rs.next()){
    //Mais codigo aqui
    Date dtNasc = rs.getDate("dt_nasc");
    Calendar cal = Calendar.getInstance();
    cal.setTime(dtNasc);
    int ano = cal.get(Calendar.YEAR);
    //Se quiser ser mais detalhista, leia o mês e o dia e faça o cálculo de diferença de anos, meses e dias para a idade correta
    int soma = 1;
    if(clientesPorIdade.hasKey(ano)) {
        soma += clientesPorIdade.get(ano);
    }
    clientesPorIdade.put(ano, soma);
}

Creio que isso ajude a dar um norte.

1 curtida

Excelente aula.

Vou ver isso, mas realmente parece ser a luz no fim do túnel. Obrigado pela excelente explicação.

Imagina.
Eu nem sou tão bom assim com Criteria ou mesmo com SQL.
Só tive a oportunidade de ter experiências (a maioria delas foi ruim) e conseguir ter tal visão.

1 curtida