Transformar linhas em colunas

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
fabkons
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 08 Abr 2010 9:14 am
Localização: Florianopolis - Santa Catarina

Oi Pessoal Boa Tarde preciso de ajuda para solucionar um problema
que estou enfrentando em algumas consultas sql,

tenho uma tabela chamada f_admissao e preciso retornar no sql da seguinte forma, tenho varios eventos com valores em linhas preciso que esse valores retornem em colunas da seguinte forma;

Selecionar tudo

DAta,          valorsalario, valorferias, valor13salario
01/08/2011  1200            1300          1500
f_admissao


campos

Selecionar tudo

Data,           eventos ,   nome,      valor 
01/08/2011   01            salario      1200
01/08/2011   02             ferias        1300
01/08/2011   03             13salario   1500  
Abs!
ishii
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 82
Registrado em: Ter, 28 Dez 2010 7:41 pm
Localização: São Paulo - SP

Olá,

Que da para fazer, com certeza! Coloque a estrutura da tabela e seus relacionamentos com alguns dados para exemplo, pois na tabela f_admissao não ficou claro como eu distinguo os eventos (01,02,03) do resultado que você quer....

[]s Ishii
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

É sempre importane postar a versão do seu banco também... Pois dá pra fazer usando a cláusula PIVOT ou não, dependedo da versão (no caso 11g).

http://orafaq.com/wiki/PIVOT

Senão, você vai conseguir o mesmo resultado só com subconsultas...
fabkons
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 08 Abr 2010 9:14 am
Localização: Florianopolis - Santa Catarina

Na verdade e o seguinte, tenho essa query abaixo o problema a ser resolvido e tentei resolver com case so que não estou conseguindo as duas selecoes case deveriam retornar os dois valores mas quando existe o evento 977 não retorna o evento 63 e vice-versa.. não sei se fui bem claro

A versao do meu oracle e 10G

Selecionar tudo

SELECT UNIQUE l.den_uni_funcio,
       d.cod_empresa,
       d.num_matricula,
       r.nom_funcionario,
       h.nom_respons,
       r.dat_admis,
       u.cod_cargo,
       CASE COD_EVENTO
         WHEN A.COD_EVENTO = '977' AND A.NUM_MATRICULA = D.NUM_MATRICULA THEN
          A.VAL_EVENTO
       END MULTAFGTS,
       CASE
         WHEN COD_EVENTO AND A.COD_EVENTO = '63' AND
              A.NUM_MATRICULA = D.NUM_MATRICULA THEN
          A.VAL_EVENTO
       END AVPREV,
       k.den_cargo,
       d.dat_demis,
       u.dat_pagto,
       d.cod_forma_demis,
       f.des_forma_demis,
       d.cod_mot_demis,
       g.des_mot_demis,
       d.dat_aviso_previo,
       d.dat_fim_aviso,
       d.num_dias_aviso,
       u.val_saldo_fgts,
       u.salario_rescisao,
       u.val_liquido,
       u.cod_uni_funcio
  FROM demitidos d
  LEFT OUTER JOIN movto_demitidos A
    ON A.NUM_MATRICULA = d.NUM_MATRICULA
   AND A.COD_EMPRESA = d.COD_EMPRESA
--AND a.cod_evento IN ('63','977')
  left outer join dados_rescisao u
    ON u.cod_empresa = d.cod_empresa
   AND u.num_matricula = d.num_matricula
  left outer join unidade_funcional l
    ON l.cod_uni_funcio = u.cod_uni_funcio
   AND l.cod_empresa = u.cod_empresa
   AND l.dat_validade_fim > = sysdate
  left outer join cargo k
    ON k.cod_cargo = u.cod_cargo
   AND k.cod_empresa = u.cod_empresa
   AND k.dat_validade_fim > SYSDATE
  left outer join forma_demissao f
    ON f.cod_forma_demis = d.cod_forma_demis
   and f.cod_empresa = d.cod_empresa
   AND f.dat_validade_fim > SYSDATE
  left outer join motivo_demissao g
    ON g.cod_mot_demis = d.cod_mot_demis
   and g.cod_empresa = d.cod_empresa
   AND g.dat_validade_fim > SYSDATE
  left outer join funcionario r
    ON r.num_matricula = d.num_matricula
   AND r.cod_empresa = d.cod_empresa
  left outer join RHU_RESP_UNI_FUNC h
    ON h.unid_funcional = l.cod_uni_funcio
   AND h.empresa = l.cod_empresa
   AND h.dat_valid_final > = SYSDATE
 WHERE d.dat_demis > = '01/08/2011'
marcus.kobel
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qui, 12 Mai 2011 4:54 pm
Localização: Porto Alegre - RS

Tu vai ter que usar sub consulta e DECODE(), conforme o link enviado pelo BURGA acima.

Ou seja, faz a tua consulta normalmente e ela vai retornar (digamos) 10 registros praquele funcionario. Pra cada linha, tu vai quer que ter uma especie de identificador pra saber a qual valor se refere aquela linha (como tu mesmo citou, algo do tipo "valorsalario", "beneficiorefeicao", "13salario", etc.)

Ai eu bota uma consulta por fora, agrupando essas linhas todas pelo (digamos) ID do funcionario. E no agrupamento tu usa DECODE pra cada um dos campos que tu tem interesse em mostrar.

Exemplo:

SELECT funcionarioID,
SUM( DECODE( tipo_evento, 'valorsalario', valor, 0 ) ) AS salario
SUM( DECODE( tipo_evento, 'beneficiorefeicao', valor, 0 ) ) AS refeicao
SUM( DECODE( tipo_evento, '13salario', valor, 0 ) ) AS 13salario
........

e assim por diante, conforme o numero de campos que tu tiver pra consultar. Esse teu caso é bem fácil.
Eu já fiz coisa bem mais complicada que isso, e funcionou. Mas a idéia era essa, transformar várias linhas em uma só.
renan_pre
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 50
Registrado em: Ter, 10 Abr 2007 11:08 am
Localização: São Paulo - SP
M. Renan

Veja se resolve:

Selecionar tudo

select data,
       sum(valorsalario) valorsalario,
       sum(valorferias) valorferias,
       sum(valor13salario) valor13salario
  from (
select data,
       valor valorsalario,
       0 valorferias,
       0 valor13salario
  from f_admissao 
 where evento = 1 -- salario
union
select data,
       0 valorsalario,
       valor valorferias,
       0 valor13salario
  from f_admissao 
 where evento = 2 -- ferias
union
select data,
       0 valorsalario,
       0 valorferias,
       valor valor13salario
  from f_admissao 
 where evento = 3 -- 13salario
)
group by data
Teria que ser um UNION para cada evento.
Isso é inviável se forem muitos eventos e se o cadastro de eventos sofrer constantes alterações.

Abs
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante