Fórum Como transformar vários registros em apenas um convertendo os dados de um campo em nome de colunas? #130886
23/03/2010
0
TIMEF ANO PONTOS
FLAMENGO 2002 16
FLAMENGO 2003 18
FLAMENGO 2004 21
PALMEIRAS 2002 15
PALMEIRAS 2003 17
PALMEIRAS 2004 14
INTER 2002 18
INTER 2003 17
INTER 2004 20
SAO PAULO 2002 17
SAO PAULO 2003 19
SAO PAULO 2004 19
como poderia usando SQL selecionar de forma que teria apenas um registro distinto para cada time, e que cada ano fosse convertido em nome de coluna com os respectivos pontos
Exemplo de resultado desejado:
TIMEF 2002 2003 2004
FLAMENGO 16 18 21
PALMEIRAS 15 17 14
INTER 18 17 20
SAO PAULO 17 19 19
Agradeço por todas dicas, exemplos, trechos de códigos SQL, outros exemplos de SQL com o mesmo propósito, etc
Delmar
Delmar Observação)
Curtir tópico
+ 0Posts
23/03/2010
Marcelo Cavalcanti
--------------------------------------------------------------------
www.swg2.com.br (Transformando suas informações em dados gerenciais)
Gostei + 0
23/03/2010
Delmar Observação)
Sim, já pensei em tratar via código onde eu faria uma sql para pegar os anos distintos para criar em tempo de execução as colunas em uma grid, uma outra sql para pegar os times distintos e adicionar em uma grid as n linhas e, no terceiro passo, iria percorrer todos os registros da minha tabela (consulta) e localizar na grid o registro/coluna e add o valor.
Mas o objetivo é exatamente tentar desvendar uma forma de fazer isso via SQL para simplificar este trabalho. Por isso postei aí para ver se levanto algumas ideias.
De qualquer forma obrigado
Gostei + 0
23/03/2010
Thiago Santana
Espero ter ajudado.... AbraçoO
Gostei + 0
23/03/2010
Emerson Nascimento
Gostei + 0
23/03/2010
Delmar Observação)
País: Brasil
Estado: SE
Cidade: Aracaju
Mensagens: 267
Usuário DevMaster
#ID: 130897 Postado em: 23/3/2010 2:27:43 PM
Delmar vc deverá criar uma tabela com os respectivos campos e colunas! Assim irá ter as colunas TimeF, 2002, 2003 e 2004, mas tbem deverá ter chaves estrangeiras. Passando os valores comparando. Mas acho que vc deverá utilizar uma Procedure e não apenas um SQL! Tenta postar algo do SQL que vc está tentando fazer! Assim teremos mais facilidade em tentarmos resolver esta duvida!
Espero ter ajudado.... AbraçoO
Olá ThiiaGuinho
Esqueci de dizer, as colunas são registros porque as colunas não podem ser fixas neste caso de uso.
Neste exemplo as colunas deveriam ser anos, mas como nunca sei quais são os anos não posso fixá-los como colunas em minha tabela física.
Por isso acabo tendo vários registros.
Mas a discussão tá boa, to gostando da participação, das ideias e da iniciativa de cada um.
Estive tentando algo com subconsultas, como abaixo:
select timef,
(select pontos from pontuacao where timef=p.timef and ano=2002) as ano_2002,
(select pontos from pontuacao where timef=p.timef and ano=2003) as ano_2003,
(select pontos from pontuacao where timef=p.timef and ano=2004) as ano_2004
from
(select distinct(timef) from pontuacao) p
Porém, no exemplo, iria usar uma sql auxiliar para iterar os anos distintos para montar a parte que seleciona as colunas.
Só que não gosto desta sql, porque ela tem muitos select nos campos, o que poderia ficar lento.
Enquanto isso sigo estudando e pesquisando algo com crosstab para firebird
Gostei + 0
23/03/2010
Thiago Santana
Espero ter ajudado!
AbraçoO
Gostei + 0
23/03/2010
Emerson Nascimento
Gostei + 0
23/03/2010
Delmar Observação)
Ambos os códigos abaixo funcionam, sendo bem melhor que os selects nos campos. Mas tenho que usar uma função de agregação, como o max ou o min. Neste caso dá certo, porque não há repetição de registro dentro do mesmo time e ano (campo único timef+ano), ou seja, eu terei apenas um valor e fazer max ou min sobre um único valor resulta o próprio valor.
SELECT TIMEF,
MAX(CASE WHEN ANO = '2002' THEN PONTOS END) AS ANO2002,
MAX(CASE WHEN ANO = '2003' THEN PONTOS END) AS ANO2003,
MAX(CASE WHEN ANO = '2004' THEN PONTOS END) AS ANO2004
FROM PONTUACAO
GROUP BY TIMEF
SELECT TIMEF,
MIN(CASE WHEN ANO = '2002' THEN PONTOS END) AS ANO2002,
MIN(CASE WHEN ANO = '2003' THEN PONTOS END) AS ANO2003,
MIN(CASE WHEN ANO = '2004' THEN PONTOS END) AS ANO2004
FROM PONTUACAO
GROUP BY TIMEF
E agora eu posso usar uma query auxiliar para iterar e formar as colunas dinamicamente como eu vinha pensando.
A lógica aí é agrupar os registros e depois usar o case e uma query auxiliar, para desagrupar em colunas.
Mas se alguém tiver outra ideia para evitar o uso da função max/min, manda aí que vamos estudar com carinho.
Obrigado Emerson e demais colegas, pois somadas as preciosas dicas, estou caminhando ruma a solução que estava idealizando e que me agrada mais.
Gostei + 0
23/03/2010
Delmar Observação)
É isso aí galera. Amanhã continuo as buscas e testes sobre uma possível melhoria no código e na otimização.
Gostei + 0
25/03/2010
Edinei Colli
Outro detalhe, se for imprimir um relatório em que existam muitos anos a serem listados, provavelmente alguns ficarão de fora da pagina.
Talvez o select abaixo seja uma solução prática e somente com duas colunas:
SELECT
TIMEF
,ano || ': ' || sum(PONTOS)|| ' pontos.' as "Ano/Ponto(s)"
FROM PONTUACAO
GROUP BY TIMEF, ANO
ORDER BY ANO, TIMEF;
Outro detalhe que devemos levar em conta para tentar a solução para esse problema é qual a chave da sua tabela pontuacao?Será gravado 1 ou mais registros para cada clube em 1 ano?Quantos anos serão armazenados?Entre outras perguntas que poderiam auxiliar.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)