Criar sql para separar pessoas por grupos de idade  XML
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Autor Mensagem
fabiobh
JavaEvangelist

Membro desde: 30/12/2010 13:56:57
Mensagens: 386
Offline

Oi gente, tudo bem,
to apanhando um pouco do sql aki, porém preciso fazer o seguinte relatório,
preciso fazer um relatorio que traga o nome das pessoas e suas respectivas idades, eu fiz o seguinte abaixo e funcionou:


Porém agora preciso fazer um relatório que divida as pessoas entre grupos de idade.
Exemplo

Grupo de idade - Quantidade de pessoas
<=20 - 4
25-30 - 8
31-30 - 2
36-30 - 5
.
.
.
86-90 - 2
>91

Porém não faço ideia de como faze-lo, alguém poderia dar um help
ps: uso mysql
drsmachado
GUJ Expert

Membro desde: 25/09/2010 12:54:06
Mensagens: 3986
Localização: Curitiba / São José dos Pinhais - PR
Offline

Camarada, com certeza você precisará de um select gigantesco.
Eu sugiro pensar em uma stored procedure...

Rumo aos 4000
"Os homens de verdade assumem suas responsabilidades e culpas. Esquivar-se e dar desculpas é atitude dos tolos, que preferem não se comprometer".

Lugar de perguntar é no fórum!
Não respondo via MP
Não respondo por Email
Não respondo por IM
fabiobh
JavaEvangelist

Membro desde: 30/12/2010 13:56:57
Mensagens: 386
Offline

O que seria uma stored procedure? Como se usa?
ssh
JavaEvangelist
[Avatar]

Membro desde: 08/10/2011 11:18:37
Mensagens: 413
Offline

Wikipedia: Procedimento armazenado ou Stored Procedure é uma coleção de comandos em SQL para dispensamento de Banco de dados. Encapsula tarefas repetitivas, aceita parâmetros de entrada e retorna um valor de status (para indicar aceitação ou falha na execução). O procedimento armazenado pode reduzir o tráfego na rede, melhorar a performance, criar mecanismos de segurança, etc.
drsmachado
GUJ Expert

Membro desde: 25/09/2010 12:54:06
Mensagens: 3986
Localização: Curitiba / São José dos Pinhais - PR
Offline

fabiobh wrote:O que seria uma stored procedure? Como se usa?


Uma stored procedure é como um programa, escrito para ser pre compilado e rodar direto no SGBD.
Bancos mais antigos como o SQL Server e Oracle possuem implementação há muito tempo.
MySQL, apenas a partir da versão 5.

Como qualquer outro programa, uma SP contém:
Entrada
Processamento
Saída
Onde:
Entrada: Recebe argumentos (partindo de zero);
Processamento: Realiza as ações programadas, dependentes dos argumentos inseridos ou não;
Saída: Retorna o resultado do processamento (pode ser um retorno vazio ou especificado).

Aqui tem um link com muita coisa legal para isso.

http://dev.mysql.com/doc/refman/4.1/pt/create-procedure.html

Rumo aos 4000
"Os homens de verdade assumem suas responsabilidades e culpas. Esquivar-se e dar desculpas é atitude dos tolos, que preferem não se comprometer".

Lugar de perguntar é no fórum!
Não respondo via MP
Não respondo por Email
Não respondo por IM
drsmachado
GUJ Expert

Membro desde: 25/09/2010 12:54:06
Mensagens: 3986
Localização: Curitiba / São José dos Pinhais - PR
Offline

No teu caso, para cada faixa, você pode fazer um select count, para determinar a quantidade de pessoas naquela faixa etária.
Depois, concatena o resultado numa variável e retorna ela.

Rumo aos 4000
"Os homens de verdade assumem suas responsabilidades e culpas. Esquivar-se e dar desculpas é atitude dos tolos, que preferem não se comprometer".

Lugar de perguntar é no fórum!
Não respondo via MP
Não respondo por Email
Não respondo por IM
evefuji
GUJ Ranger

Membro desde: 14/12/2007 22:37:17
Mensagens: 753
Offline

Nem precisa de SQL enorme (não mexi na lógica do cálculo de idade, mas acho que dá para otimizar isso):
mauricioadl
GUJ Master
[Avatar]

Membro desde: 10/05/2007 14:52:21
Mensagens: 1140
Offline

bom o que voce precisa nao eh uma store procedure e sim uma view.

pesquise sobre o group by, eh meio chato de entender no comeco, mas com o tempo vc se acostuma.

[]'s

Seu problema foi resolvido? Por favor, edite seu primeiro post e adicione [RESOLVIDO] no título.
O forum agradece.
[Email] [MSN]
ManoJava
JavaEvangelist
[Avatar]

Membro desde: 23/04/2009 09:18:23
Mensagens: 480
Localização: Mococa-SP
Offline

Boa tarde!!

Bem simples isso, utilize uma clausula WHERE no seu select incluindo BETWEEN idade1 and idade2 e adicione um COUNT() para que te retorne a quantidade de pessoas em cada faixa de idade.

Por exemplo:



Att.

"Há Três coisas que nunca voltam atrás: A flecha lançada, a palavra pronunciada e a oportunidade perdida." - Provérbio Chinês

In Guj We Trust!

Bacharel em Ciência da Computação
MBA - Gestão de Projetos
[WWW]
fabiobh
JavaEvangelist

Membro desde: 30/12/2010 13:56:57
Mensagens: 386
Offline

ManoJava wrote:
Bem simples isso, utilize uma clausula WHERE no seu select incluindo BETWEEN idade1 and idade2 e adicione um COUNT() para que te retorne a quantidade de pessoas em cada faixa de idade.
SELECT
COUNT(pes_nom_completo,pes_data_nascimento,(YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5))) AS idade
FROM
pessoas
WHERE pes_nom_completo,pes_data_nascimento,(YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5))
BETWEEN parametro1 and parametro2


Essa sentença funcionou depois que fiz uma pequena mudança nela

Porém eu teria que repeti-la para cada intervalo de idade, acho q pode ser mais otimizado, mas já é um bom começo.

evefuji wrote:
Nem precisa de SQL enorme (não mexi na lógica do cálculo de idade, mas acho que dá para otimizar isso):
SELECT
CASE WHEN (YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5)) < 20 then '<20'
ELSE Trunc((YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5))/5)*5
END as Faixa_de_idade,
Count(*)
FROM pessoas
GROUP BY 1

Eu removi o Trunc(o mysql workbench falou q tal função não existia) e removi a multiplicação por 5 no final do else e a sentença funcionou trazendo os seguintes resultados
Faixa de idade - Quant Pessoas
35.0000 - 2
37.0000 - 1
42.0000 - 1
46.0000 - 1
49.0000 - 1
61.0000 - 1
64.0000 - 1
65.0000 - 1
80.0000 - 1
83.0000 - 1
<20 - 1

Foi bem feita a sentença, porém como eu nunca tinha usado CASE e END numa sentença sql, fiquei meio sem entender o q aconteceu, agora tenho q tentar agrupar o resultado dentro das faixas de idade, em vez de categorizar por cada idade
ADEMILTON
JavaGuru

Membro desde: 29/04/2006 17:53:21
Mensagens: 236
Offline

A solução dada pelo evefuji é a mais eficiente de todas. Vou só tentar contribuir com o modo como fazemos cálculo de idade aqui:



o .25 corresponde ao chorinho de um dia dos anos bissextos...

Então... no caso, como você quer agrupar por faixas ficaria tipo assim:



Veja se o trunc não existe mesmo, deve ter outra função no lugar dele pra pegar só a parte inteira do resultado da operação

This message was edited 1 time. Last update was at 21/12/2011 11:46:56

[MSN]
drsmachado
GUJ Expert

Membro desde: 25/09/2010 12:54:06
Mensagens: 3986
Localização: Curitiba / São José dos Pinhais - PR
Offline

Por esse motivo havia sugerido stored procedure.
Você conseguiria criar os selects isoladamente e, ao fim, concatenar todos os resultados em uma única saída, formatada.
Talvez um cursor já resolvesse, também.
Enfim, há várias formas de se resolver isto, o ideal é que você foque em uma e vá até o fim com ela.
Dúvidas, poste aqui.

Rumo aos 4000
"Os homens de verdade assumem suas responsabilidades e culpas. Esquivar-se e dar desculpas é atitude dos tolos, que preferem não se comprometer".

Lugar de perguntar é no fórum!
Não respondo via MP
Não respondo por Email
Não respondo por IM
drsmachado
GUJ Expert

Membro desde: 25/09/2010 12:54:06
Mensagens: 3986
Localização: Curitiba / São José dos Pinhais - PR
Offline

ADEMILTON wrote:A solução dada pelo evefuji é a mais eficiente de todas. Vou só tentar contribuir com o modo como fazemos cálculo de idade aqui:



o .25 corresponde ao chorinho de um dia dos anos bissextos...

Não seria concat????

Rumo aos 4000
"Os homens de verdade assumem suas responsabilidades e culpas. Esquivar-se e dar desculpas é atitude dos tolos, que preferem não se comprometer".

Lugar de perguntar é no fórum!
Não respondo via MP
Não respondo por Email
Não respondo por IM
ADEMILTON
JavaGuru

Membro desde: 29/04/2006 17:53:21
Mensagens: 236
Offline

drsmachado wrote:
ADEMILTON wrote:A solução dada pelo evefuji é a mais eficiente de todas. Vou só tentar contribuir com o modo como fazemos cálculo de idade aqui:



o .25 corresponde ao chorinho de um dia dos anos bissextos...

Não seria concat????


Não, não, colega... faço exatamente do jeito que coloquei, só que no meu caso uso a função sysdate() porque aqui é Oracle.
[MSN]
ManoJava
JavaEvangelist
[Avatar]

Membro desde: 23/04/2009 09:18:23
Mensagens: 480
Localização: Mococa-SP
Offline

fabiobh wrote:
ManoJava wrote:
Bem simples isso, utilize uma clausula WHERE no seu select incluindo BETWEEN idade1 and idade2 e adicione um COUNT() para que te retorne a quantidade de pessoas em cada faixa de idade.
SELECT
COUNT(pes_nom_completo,pes_data_nascimento,(YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5))) AS idade
FROM
pessoas
WHERE pes_nom_completo,pes_data_nascimento,(YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5))
BETWEEN parametro1 and parametro2


Essa sentença funcionou depois que fiz uma pequena mudança nela

Porém eu teria que repeti-la para cada intervalo de idade, acho q pode ser mais otimizado, mas já é um bom começo.

evefuji wrote:
Nem precisa de SQL enorme (não mexi na lógica do cálculo de idade, mas acho que dá para otimizar isso):
SELECT
CASE WHEN (YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5)) < 20 then '<20'
ELSE Trunc((YEAR(CURDATE())-YEAR(pes_data_nascimento)) - (RIGHT(CURDATE(),5)<RIGHT(pes_data_nascimento,5))/5)*5
END as Faixa_de_idade,
Count(*)
FROM pessoas
GROUP BY 1

Eu removi o Trunc(o mysql workbench falou q tal função não existia) e removi a multiplicação por 5 no final do else e a sentença funcionou trazendo os seguintes resultados
Faixa de idade - Quant Pessoas
35.0000 - 2
37.0000 - 1
42.0000 - 1
46.0000 - 1
49.0000 - 1
61.0000 - 1
64.0000 - 1
65.0000 - 1
80.0000 - 1
83.0000 - 1
<20 - 1

Foi bem feita a sentença, porém como eu nunca tinha usado CASE e END numa sentença sql, fiquei meio sem entender o q aconteceu, agora tenho q tentar agrupar o resultado dentro das faixas de idade, em vez de categorizar por cada idade


Otimização é a palavra chave, apesar que a diferença de performance é imperceptível, mas sempre é recomendado resumir ao maximo as sentenças, lógico que respeitando sempre as limitações de cada BD.

Att.

"Há Três coisas que nunca voltam atrás: A flecha lançada, a palavra pronunciada e a oportunidade perdida." - Provérbio Chinês

In Guj We Trust!

Bacharel em Ciência da Computação
MBA - Gestão de Projetos
[WWW]
 
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Ir para:   
Powered by JForum 2.1.8 © JForum Team