Calcular a quantidade de clientes por idade

7 respostas Resolvido
java
G

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

7 Respostas

R

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

G

@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.

L

@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.

L
Solucao aceita

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.

G

Excelente aula.

G

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

L

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.

Criado 23 de março de 2017
Ultima resposta 23 de mar. de 2017
Respostas 7
Participantes 3