Fórum Separar linhas em colunas postgresql #484774

07/07/2014

0

Bom dia amigos,
estou com dificuldades no postgre SQL em separar linhas em colunas, por exemplo:

Tenho os seguintes dados:

Data | Máquina | Qtd
01/07/2014 | serra 1 | 12
01/07/2014 | serra 2 | 18
02/07/2014 | serra 1 | 14
02/07/2014 | serra 2 | 15

Quero apresentar da seguinte forma:

Máquina | 01/07/2014 | 02/07/2014
serra 1 | 12 | 14
serra 2 | 18 | 15

e assim sucessivamente conforme for abastecendo o banco com mais datas...

Grato.
Renan Maia

Renan Maia

Responder

Post mais votado

07/07/2014

Bom, criei uma função com base nos dados que você me passou. A forma que pensei foi mostrar através do RAISE NOTICE a formatação que você deseja, mas fique a vontade para mudar se precisar.

CREATE OR REPLACE FUNCTION public.func_dados_serra (
)
RETURNS void AS
$body$
DECLARE 
r						    RECORD;
p							RECORD;
q							RECORD;
qtd_aux						integer;
cabecalho	 				text;
linha						text;
BEGIN 
   
    cabecalho = 'MAQUINA';    
	
	FOR r IN SELECT data FROM dados_serra GROUP BY data ORDER BY data ASC
	LOOP
	cabecalho = cabecalho || ' | ' || r.data;         
	END LOOP;   
    
    RAISE NOTICE '%',cabecalho;
    
     FOR p IN SELECT maquina FROM dados_serra GROUP BY maquina
     LOOP   
        linha = p.maquina;
		
        FOR q IN SELECT qtd FROM dados_serra WHERE maquina = p.maquina ORDER BY data ASC        
        LOOP 
         linha = linha || ' | ' || q.qtd;
        END LOOP;
        
        RAISE NOTICE '%',linha;
     END LOOP;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;


Testei e a saída foi essa:

NOTICE:  MAQUINA | 2014-07-01 | 2014-07-02
NOTICE:  serra 1 | 12 | 14
NOTICE:  serra 2 | 18 | 15
Total query runtime: 33 ms.
1 row retrieved.

Ronaldo Lanhellas

Ronaldo Lanhellas
Responder

Gostei + 1

Mais Posts

07/07/2014

Ronaldo Lanhellas

No seu caso notei que as colunas são dinâmicas, pois podem existir diversas datas e você não tem como saber quantas são. A melhor solução seria criar uma função que montasse o seu SQL de forma dinâmica.
Responder

Gostei + 0

07/07/2014

Renan Maia

Obrigado pela resposta Ronaldo,
Porém sou novo na área de programação etc... poderia me dar um exemplo de como fazer isso?

Mais uma vez obrigado.
Responder

Gostei + 0

07/07/2014

Fabiano Carvalho

Pesquise por pivot ou crosstab, se voce informar as datas manualmente irá fazer o que voce deseja, mas é aconselhado a fazer a função como foi indicado.
Não posso te ajudar tanto pois não trabalho com postgre, mas pela pesquisa rápida encontrei algumas soluções.
Responder

Gostei + 0

07/07/2014

Ronaldo Lanhellas

Vou preparar um exemplo e já lhe repasso.
Responder

Gostei + 0

07/07/2014

Renan Maia

Ótimo Ronaldo, muito obrigado pela ajuda, ainda não testei mas creio que irá funcionar.
Fabiano, obrigado pela dica.


Att
Renan.
Responder

Gostei + 0

07/07/2014

Ronaldo Lanhellas

Bom, funcionar funciona, partindo da estrutura de tabela que você passou no início do post, só não sei se é exatamente o que você precisa. De qualquer forma, já é um começo e você pode adaptar para sua necessidade.
Responder

Gostei + 0

07/07/2014

Renan Maia

Fiz todos os teste agora a tarde, porem achei a solução para meu problema, o FastReport possui o objeto Cross Tab, que pode ser ordenado de forma visual a tabela.
Portanto, se alguém tiver o mesmo problema, o fast possui uma solução fácil.
Responder

Gostei + 0

07/07/2014

Ronaldo Lanhellas

Bom, de fato usar uma IDE para construção de relatório simplifica tudo, mas como você não exemplificou para que precisava disso, não tinha como opinar.
Responder

Gostei + 0

09/07/2014

Renan Maia

Bom, eu precisava extrair do banco de dados e apresentar de alguma forma, apos quebrar a cabeça a tarde toda é que veio a ideia de montar um gerador de relatórios pra simplificar tudo :).

Mas agora estou com um novo problema, tenho a seguinte linha de comando na Query/postgres, que seleciona a tabela de tempo parado de cada máquina e apresenta numa query...

select pa.ds_parada, sum(ap.qtd_minutoparado) as minutos
from apontador ap
inner join paradas pa on pa.seq = ap.cd_parada
where ap.cd_horas = 11 and ap.dt_apontador between '01/07/2014' and '09/07/2014'
group by pa.ds_parada

.... que me traz os seguintes dados no postgres...

"RETRABALHO";250
"TROCA DE FERRAMENTAS/SETUP";2040
"FALTA DE PROGRAMACAO";75
"FALHA MECANICA";135
"CAFÉ/ALIMENTAÇÃO";90
"FALHA ELETRICA";1310
"FALTA DE EXAUSTAO";175
"FALTA DE MATERIA PRIMA";1100
"REUNIAO/TREINAMENTO";60
"FALTA DE AR COMPRIMIDO";135
"FALTA DE COLABORADOR";180
"FALTA DE EMPILHADEIRA";60

...existe aluma função especifica no POSTGRES para converter os valores que estão em minutos para horas, pois só dividir por exemplo os 250 minutos da primeira linha por 60 não resolve o problema.

Grato.
Responder

Gostei + 0

09/07/2014

Ronaldo Lanhellas

Porque não resolve o problema ? Qual o tipo de dado da sua coluna ?

Pois se fizer isso:

SELECT 250/4; 


Verá que o resultado = 4, minutos.
Responder

Gostei + 0

09/07/2014

Ronaldo Lanhellas

Porque não resolve o problema ? Qual o tipo de dado da sua coluna ?

Pois se fizer isso:

SELECT 250/4; 


Verá que o resultado = 4, minutos.


Desculpe, corrigindo o codigo acima:

SELECT 250/60; 
Responder

Gostei + 0

09/07/2014

Renan Maia

A coluna minutos é do tipo integer, logo se eu dividir 250 por 60 = 4,16 horas, até ai tudo bem, sei que são 4 horas e pra eu saber o valor do ,16 é tenho que multiplicar novamente por 60 pra saber quantos minutos representam 0,16. O problema é que não sei como pegar somente o ,16 e multiplica por 60.
Responder

Gostei + 0

09/07/2014

Ronaldo Lanhellas

Tente assim:

select (250/60) as hora, (250.0/60.0) - (250/60) as minutos;
Responder

Gostei + 0

09/07/2014

Renan Maia

Ronaldo, deu certo assim. Retornou 4 horas, 10 minutos.

#Código
select (250/60) as hora, ((250.0/60.0) - (250/60))*60 as minutos;
Responder

Gostei + 0

09/07/2014

Ronaldo Lanhellas

Ótimo, que bom que deu certo.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar