Preciso de ajuda para obter umas informações no meu banco de dados

Oracle

03/10/2014

Pessoal,

Preciso criar um select que retorne o histórico de compras de um determinado cliente, por mês,

exemplo: cliente x, comprou 1,00 em janeiro, 2,00 em fevereiro e assim sucessivamente.

Se eu fizer um select com o resultado do primeiro mês e fizer um union, repetindo o mesmo select alterando apenas o período, conseguirei as informações que preciso, porem as informações serão retornadas uma linha para cada mês, mas o que preciso é que as informações sejam retornadas por colunas,

exemplo: coluna 1 cliente, coluna 2 valor comprado em janeiro, coluna 3 valor comprado em fevereiro e assim sucessivamente...

É possível fazer da forma que preciso?

Meu banco de dados é Oracle e uso o PLSQL para realizar as consultas.


Obrigado
Gustavo Silva

Gustavo Silva

Curtidas 0

Melhor post

Ronaldo Lanhellas

Ronaldo Lanhellas

03/10/2014

Exatamente, o recurso Pivot e Unpivot é o caminho. Veja: http://www.oracle.com/technetwork/pt/articles/sql/principais-caracteristicas-database-2108383-ptb.html
GOSTEI 2

Mais Respostas

Alex Lekao

Alex Lekao

03/10/2014

Ola Gustavo,

se nao me engano o recurso eh chamado de Pivot, ja vi algumas formas de fazer no sql server.

Acredito que seja igual ou similar no oracle.

Desculpe nao ajudar mais, eu nao conheco oracle, mas acho que ja seria um caminho a percorrer para tentar resolver a sua questao.

Abraco.
GOSTEI 1
Marisiana Battistella

Marisiana Battistella

03/10/2014

Se ficar com dúvidas ao utilizar o pivot, você pode postar a instrução que você fez ou então a estrutura das tabelas envolvidas...
GOSTEI 2
Gustavo Silva

Gustavo Silva

03/10/2014

Pessoal,

Pelo que li no link postado pelo Ronaldo, a função pivot só funciona no oracle 11g, no entanto, a versao do meu banco é o 10g, sendo assim, creio que o pivot não ajudará, infelizmente!

Alguma outra ideia?


Agradeço!
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Ah pois é... Então, eu acho que vc pode utilizar o DECODE. Mais ou menos como nesse trecho q peguei em um 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 

Segue um link com um exemplo: [url]http://felipeduarteshimizu.wordpress.com/2010/09/30/pl-sqloracle-transformar-linhas-para-coluna/[/url]
GOSTEI 1
Gustavo Silva

Gustavo Silva

03/10/2014

Olá Marisiana,

Sua resposta foi muito útil e com base nela consegui fazer da forma que precisava, mas aí me surgiu um novo problema que para este não sei se há uma solução... estou postando abaixo o meu select e o resultado do mesmo para tentar explicar melhor:

-------------------------------------------------------------------------------------------------
select
pe.seqpessoa,
pe.nomerazao,
seqfornecedor,
Representante,

decode( to_char(data_venda, 'MM'), 1, SUM(VLRVENDA)) as JANEIRO,
decode( to_char(data_venda, 'MM'), 1, SUM(NROITENS)) as QTDJAN,
decode( to_char(data_venda, 'MM'), 2, SUM(VLRVENDA)) as FEVEREIRO,
decode( to_char(data_venda, 'MM'), 2, SUM(NROITENS)) as QTDFEV,
decode( to_char(data_venda, 'MM'), 3, SUM(VLRVENDA)) as MARCO,
decode( to_char(data_venda, 'MM'), 3, SUM(NROITENS)) as QTDMAR

from (
select j.nrorepresentante,
min( J.APELIDO ) as Representante,
p.seqpessoa,
p.nomerazao,
z.seqfornecedor,
J2.NOMERAZAO,

count( distinct V.SEQPRODUTO )
as NROITENS,

sum( ( ( case when 'N' in ( 'S', 'V' ) then
V.VLRITEMSEMDESC else V.VLRITEM end ) - VLRICMSST - ( V.VLRDEVOLITEM - VLRDEVOLICMSST ))) as VLRVENDA,

V.DTAVDA as data_venda

from MRL_CUSTODIAFAM Y, MAXV_ABCDISTRIBBASE V, MAP_PRODUTO A, MAP_PRODUTO PB, MAP_FAMDIVISAO D,
MAP_FAMEMBALAGEM K, MAX_EMPRESA E, MAD_REPRESENTANTE J, GE_PESSOA P, GE_PESSOA J2, MRLV_DESCONTOREGRA RE, MAP_FAMFORNEC z

where D.SEQFAMILIA = A.SEQFAMILIA

and D.NRODIVISAO in (1)
and V.SEQPRODUTO = A.SEQPRODUTO
and V.SEQPRODUTOCUSTO = PB.SEQPRODUTO
and V.NROEMPRESA = 1
and V.NROSEGMENTO in ( 1,6,5,2,4,9,7,10,8,3 )
and V.NRODIVISAO = D.NRODIVISAO
and E.NROEMPRESA = V.NROEMPRESA
and z.seqfamilia = a.seqfamilia
and V.DTAVDA BETWEEN '01-JAN-2014' and '31-MAR-2014'
and Y.NROEMPRESA = nvl( E.NROEMPCUSTOABC, E.NROEMPRESA )
and Y.DTAENTRADASAIDA = V.DTAVDA
and K.SEQFAMILIA = A.SEQFAMILIA
and K.QTDEMBALAGEM = fPadraoEmbVenda2(D.SEQFAMILIA,'1')
AND V.SEQPRODUTO = RE.SEQPRODUTO(+)
AND V.DTAVDA = RE.DATAFATURAMENTO (+)
AND V.NRODOCTO = RE.NUMERODF (+)
AND V.SERIEDOCTO = RE.SERIEDF(+)
AND V.NROEMPRESA = RE.NROEMPRESA (+)
and Y.SEQFAMILIA = PB.SEQFAMILIA (+)
and V.NROREPRESENTANTE = J.NROREPRESENTANTE
AND Z.SEQFORNECEDOR = J2.SEQPESSOA
AND P.SEQPESSOA = 2245
and V.SEQPESSOA = P.SEQPESSOA

and DECODE(V.TIPTABELA, 'S', V.CGOACMCOMPRAVENDA, V.ACMCOMPRAVENDA) in ( 'S', 'I' )
and exists ( select 1
from MAP_FAMFORNEC
where SEQFORNECEDOR = 277
and PRINCIPAL = 'S'
and MAP_FAMFORNEC.SEQFAMILIA = A.SEQFAMILIA )

group by J.NROREPRESENTANTE,
p.nomerazao,
p.seqpessoa,
z.seqfornecedor,
J2.NOMERAZAO,
V.DTAVDA ) vendas,
ge_pessoa pe

where trunc(data_venda) between '01-JAN-2014' and '31-MAR-2014'
AND SEQFORNECEDOR = 277
and vendas.seqpessoa = pe.seqpessoa

Group by
Representante,
pe.seqpessoa,
pe.nomerazao,
seqfornecedor,
NROITENS,
data_venda

order by 4,1

--------------------------------------------------------------------------------------------------------------

O resultado foi este abaixo:

[img:descricao=Resultado]http://arquivo.devmedia.com.br/forum/imagem/389411-20141007-111747.jpg[/img]

O problema é que o resultado retorna em colunas diferente, mas em linhas diferentes também, então o que preciso e não sei se é possível, é que retornem os valores por colunas diferentes, mas na mesma linha. Os meses que não tiveram vendas retornaria null e os meses que houver venda, retornaria os valores.

Agradeço muito pela ajuda de todos e desde já agradeço também pelas respostas a este questionamento!
GOSTEI 0
Alex Lekao

Alex Lekao

03/10/2014

Ola,

Eh necessario mesmo esse agrupamento utilizando o Data da Venda?

Group by Representante,pe.seqpessoa,pe.nomerazao,seqfornecedor,NROITENS,data_venda
GOSTEI 0
Gustavo Silva

Gustavo Silva

03/10/2014

Olá Alex,

Não fiz o teste retirando a data venda, mas suponho que não dará certo porque as informações precisam ser agrupadas por mês, porem se tiveres uma forma de fazer, retirando este agrupamento, fico agradecido se você me disser como fazer!

Desde já agradeço!
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Tem que incluir a data no GROUP BY porque vc está trabalhando com funções de agregação (SUM), se tirar provavelmente vai ocorrer um erro.
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Um dos motivos pra não aparecer todos na mesma linha é que tem representantes diferentes..
Mas deve ter mais alguma informação que está incluida no agrupamento e está retornando valores diferentes...
Percebi no select que vc faz um select de um subselect e que neste subselect os campos do GROUP BY estão diferentes do GROUP BY do select que retorna o resultado final.
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Reestruturei o SQL e utilizando o padrão ANSI, tinha algumas coisas que logicamente não estavam corretas nele.
Não cheguei a testar o código, compare os resultados desse com o que vc tem pra ver não alterei a regra de negócio dele pois não cheguei a testar ele...
select vendas.representante,
     vendas.seqpessoa,
     vendas.nomerazao,
     vendas.seqfornecedor,
     vendas.data_venda,
     decode( to_char(data_venda, 'MM'), 1, SUM(VLRVENDA)) as JANEIRO,
     decode( to_char(data_venda, 'MM'), 1, SUM(NROITENS)) as QTDJAN,
     decode( to_char(data_venda, 'MM'), 2, SUM(VLRVENDA)) as FEVEREIRO,
     decode( to_char(data_venda, 'MM'), 2, SUM(NROITENS)) as QTDFEV,
     decode( to_char(data_venda, 'MM'), 3, SUM(VLRVENDA)) as MARCO,
     decode( to_char(data_venda, 'MM'), 3, SUM(NROITENS)) as QTDMAR	
from (select j.nrorepresentante,
             min( J.APELIDO ) as representante,
             p.seqpessoa,
             p.nomerazao,
             z.seqfornecedor,
             V.DTAVDA as data_venda,
             count( distinct V.SEQPRODUTO )  as NROITENS, 
             sum( ( ( case	
                         when	'N' in ( 'S', 'V' ) then 
                               V.VLRITEMSEMDESC 
                         else	
                                V.VLRITEM 
                         end ) - VLRICMSST - ( V.VLRDEVOLITEM - VLRDEVOLICMSST ))
                 ) as VLRVENDA   
       from MAXV_ABCDISTRIBBASE V   
       join MAP_FAMDIVISAO D    
       on V.NRODIVISAO = D.NRODIVISAO 
       join MAP_PRODUTO A
       on A.SEQFAMILIA = D.SEQFAMILIA  
       and A.SEQPRODUTO = V.SEQPRODUTO
       join MRL_CUSTODIAFAM Y
       on Y.DTAENTRADASAIDA = V.DTAVDA 
       left join MAP_PRODUTO PB
       on PB.SEQPRODUTO = V.SEQPRODUTOCUSTO  
       and PB.SEQFAMILIA = Y.SEQFAMILIA 
       join MAX_EMPRESA E
       on E.NROEMPRESA = V.NROEMPRESA
       join  MAP_FAMFORNEC Z
       on z.seqfamilia = a.seqfamilia
       join MAP_FAMEMBALAGEM K
       on K.SEQFAMILIA = A.SEQFAMILIA 
       left join MRLV_DESCONTOREGRA RE
       on RE.SEQPRODUTO = V.SEQPRODUTO
       and RE.DATAFATURAMENTO = V.DTAVDA
       and RE.NUMERODF = V.NRODOCTO
       and RE.SERIEDF = V.SERIEDOCTO
       and RE.NROEMPRESA = V.NROEMPRESA 
       join MAD_REPRESENTANTE J
       on J.NROREPRESENTANTE = V.NROREPRESENTANTE
       join GE_PESSOA J2
       on J2.SEQPESSOA = Z.SEQFORNECEDOR
       join GE_PESSOA P
       on P.SEQPESSOA = V.SEQPESSOA
       where D.NRODIVISAO in (1) 
       and V.NROEMPRESA = 1 
       and V.NROSEGMENTO in ( 1,6,5,2,4,9,7,10,8,3 )  
       and V.DTAVDA BETWEEN '01-JAN-2014' and '31-MAR-2014' 
       and Y.NROEMPRESA = nvl( E.NROEMPCUSTOABC, E.NROEMPRESA ) 
       and K.QTDEMBALAGEM = fPadraoEmbVenda2(D.SEQFAMILIA,'1')
       and P.SEQPESSOA = 2245
       and DECODE(V.TIPTABELA, 'S', V.CGOACMCOMPRAVENDA, V.ACMCOMPRAVENDA) in ( 'S', 'I' ) 
       and exists ( select 1 
                    from MAP_FAMFORNEC  MFF
                    join MAP_PRODUTO MP
                    on MFF.SEQFAMILIA = MP.SEQFAMILIA
                    where MFF.SEQFORNECEDOR = 277
                    and MF.PRINCIPAL = 'S' ) 
       and Z.SEQFORNECEDOR = 277
       group by j.nrorepresentante,
                p.seqpessoa,
                p.nomerazao,
                z.seqfornecedor,
                V.DTAVDA ) vendas
group by vendas.representante,
        vendas.seqpessoa,
        vendas.nomerazao,
        vendas.seqfornecedor,
        vendas.data_venda,
order by vendas.representante
         vendas.seqpessoa;


Um dos motivos para não mostrar tudo em uma linha só era que tinha representantes diferentes, o outro, pode ser, que seja a data de venda que seja diferente...
GOSTEI 1
Alex Lekao

Alex Lekao

03/10/2014

Eu imaginei tambem que fosse alguma coisa referente a agrupamento nos subselects, mas como eu, honestamente, me perdi do meio do codigo. rsrsr, entao questionei a respeito da data.

Imaginei que esse comando fosse algo diferente, nao conheco oracle. rsrsr, mas eu sugiro entao fazer algo meio "marretado" se nao for essa questao do group by no subselect.

Acredito que deva funcionar no oracle tbm.

Vou postar um exemplo que imagino que seja possivel abaixo, mas primeiro, tem que colocar os campos que estiverem null retornando algum valor, preferencialmente zero, para nao interferir no resultado.

Um dos motivos pra não aparecer todos na mesma linha é que tem representantes diferentes..
Mas deve ter mais alguma informação que está incluida no agrupamento e está retornando valores diferentes...
Percebi no select que vc faz um select de um subselect e que neste subselect os campos do GROUP BY estão diferentes do GROUP BY do select que retorna o resultado final.


Segue Codigo de sugestao:
select 
   seqpessoa,
   nomerazao,
   seqfornecedor,
   Representante,
   sum(JANEIRO) as janeiro,
   sum(QTDJAN) as qtdjan,
   sum(FEVEREIRO) as fevereiro,
   sum(QTDFEV) as qtdfev,
   sum(MARCO) as marco,
   sum(QTDMAR) as qtdmar
from (
select 
   pe.seqpessoa,
   pe.nomerazao,
   seqfornecedor,
   Representante,
   decode( to_char(data_venda, 'MM'), 1, SUM(VLRVENDA)) as JANEIRO,
   decode( to_char(data_venda, 'MM'), 1, SUM(NROITENS)) as QTDJAN,
   decode( to_char(data_venda, 'MM'), 2, SUM(VLRVENDA)) as FEVEREIRO,
   decode( to_char(data_venda, 'MM'), 2, SUM(NROITENS)) as QTDFEV,
   decode( to_char(data_venda, 'MM'), 3, SUM(VLRVENDA)) as MARCO,
   decode( to_char(data_venda, 'MM'), 3, SUM(NROITENS)) as QTDMAR	
from (select 
         j.nrorepresentante,
         min( J.APELIDO ) as Representante,
         p.seqpessoa,
         p.nomerazao,
         z.seqfornecedor,
         J2.NOMERAZAO,
         count( distinct V.SEQPRODUTO ) as NROITENS, 
         sum( ( ( case	when	'N' in ( 'S', 'V' ) then V.VLRITEMSEMDESC else	V.VLRITEM end ) - VLRICMSST - ( V.VLRDEVOLITEM - VLRDEVOLICMSST ))) as VLRVENDA,
         V.DTAVDA as data_venda
      from MRL_CUSTODIAFAM Y, MAXV_ABCDISTRIBBASE V, MAP_PRODUTO A, MAP_PRODUTO PB, MAP_FAMDIVISAO D, 
           MAP_FAMEMBALAGEM K, MAX_EMPRESA E, MAD_REPRESENTANTE J, GE_PESSOA P, GE_PESSOA J2, MRLV_DESCONTOREGRA RE, MAP_FAMFORNEC z 
      where D.SEQFAMILIA = A.SEQFAMILIA 
         and D.NRODIVISAO in (1) 
         and V.SEQPRODUTO = A.SEQPRODUTO 
         and V.SEQPRODUTOCUSTO = PB.SEQPRODUTO 
         and V.NROEMPRESA = 1 
         and V.NROSEGMENTO in ( 1,6,5,2,4,9,7,10,8,3 ) 
         and V.NRODIVISAO = D.NRODIVISAO 
         and E.NROEMPRESA = V.NROEMPRESA
         and	z.seqfamilia = a.seqfamilia
         and V.DTAVDA BETWEEN '01-JAN-2014' and '31-MAR-2014' 
         and Y.NROEMPRESA = nvl( E.NROEMPCUSTOABC, E.NROEMPRESA ) 
         and Y.DTAENTRADASAIDA = V.DTAVDA 
         and K.SEQFAMILIA = A.SEQFAMILIA 
         and K.QTDEMBALAGEM = fPadraoEmbVenda2(D.SEQFAMILIA,'1') 
         AND V.SEQPRODUTO = RE.SEQPRODUTO(+) 
         AND V.DTAVDA = RE.DATAFATURAMENTO (+) 
         AND V.NRODOCTO = RE.NUMERODF (+) 
         AND V.SERIEDOCTO = RE.SERIEDF(+) 
         AND V.NROEMPRESA = RE.NROEMPRESA (+) 
         and Y.SEQFAMILIA = PB.SEQFAMILIA (+) 
         and V.NROREPRESENTANTE = J.NROREPRESENTANTE 
         AND	Z.SEQFORNECEDOR	= J2.SEQPESSOA
         AND	P.SEQPESSOA	= 2245
         and V.SEQPESSOA = P.SEQPESSOA 
         and DECODE(V.TIPTABELA, 'S', V.CGOACMCOMPRAVENDA, V.ACMCOMPRAVENDA) in ( 'S', 'I' ) 
         and exists ( select 
                         1 
                      from MAP_FAMFORNEC 
                      where SEQFORNECEDOR = 277
                         and PRINCIPAL = 'S' 
                         and MAP_FAMFORNEC.SEQFAMILIA = A.SEQFAMILIA ) 
      group by J.NROREPRESENTANTE,p.nomerazao,p.seqpessoa,z.seqfornecedor,J2.NOMERAZAO,V.DTAVDA ) vendas,ge_pessoa pe
where trunc(data_venda) between '01-JAN-2014' and '31-MAR-2014'
   AND SEQFORNECEDOR = 277
   and	vendas.seqpessoa =	pe.seqpessoa
Group by Representante,pe.seqpessoa,pe.nomerazao,seqfornecedor,NROITENS,data_venda
) as Rel
group by seqpessoa,nomerazao,seqfornecedor,Representante,
order by 4,1
GOSTEI 1
Marisiana Battistella

Marisiana Battistella

03/10/2014

Eu acho que não precisa incluir esse outro select, porque ele já soma os valores no decode e os dados já estão sendo agrupados..
Outra coisa que ele tinha errado era a ordem dos campos no GROUP BY que está diferente da ordem dos campos do SELECT...
"A ordem dos fatores altera o resultado..."
GOSTEI 1
Marisiana Battistella

Marisiana Battistella

03/10/2014

Outra coisa, no subselect ele agrupa os valores pelo "código pessoa" e no select ele tava agrupando pelo nome.
Existe diferença entre agrupar pelo nome e agrupar pelo código, visto que pode existir diferentes pessoas com o nome idêntico.
Deve-se ter esse cuidado quando for definir a regra que será aplicada na instrução SQL, pois pode alterar os resultados.
GOSTEI 1
Alex Lekao

Alex Lekao

03/10/2014

Pois eh... rsrsr

Como disse, marretar.. rsrsr

Eu honestamente nao avaliei tao bem o codigo dele, pela imagem do resultado, sugeri aquele script, dependendo ele adiantaria o resultado. rsrs

Mas blz. rsrsr
GOSTEI 0
Gustavo Silva

Gustavo Silva

03/10/2014

Pessoal,

Ao final, e agora acho que ficou correto rsrs... o select ficou praticamente igual ao que o Alex passou, praticamente, porque tive que fazer uma pequena alteração para retornar a razão social do fornecedor e incluir os outros meses!

select
AAA.seqpessoa,
AAA.nomerazao,
seqfornecedor,
J3.NOMERAZAO,
Representante,
sum(JANEIRO) as janeiro,
sum(QTDJAN) as qtdjan,
sum(FEVEREIRO) as fevereiro,
sum(QTDFEV) as qtdfev,
sum(MARCO) as marco,
sum(QTDMAR) as qtdmar,
sum(ABRIL) as abril,
sum(QTDABR) as qtdabr,
sum(MAIO) as maio,
sum(QTDMAI) as qtdmai,
sum(JUNHO) as junho,
sum(QTDJUN) as qtdjun,
sum(JULHO) as julho,
sum(QTDJUL) as qtdjul,
sum(AGOSTO) as AGOSTO,
sum(QTDAGO) as QTDAGO,
sum(SETEMBRO) as SETEMBRO,
sum(QTDSET) as QTDSET,
sum(OUTUBRO) as OUTUBRO,
sum(QTDOUT) as QTDOUT,
sum(NOVEMBRO) as NOVEMBRO,
sum(QTDNOV) as QTDNOV,
sum(DEZEMBRO) as DEZEMBRO,
sum(QTDDEZ) as QTDDEZ
from (
select
pe.seqpessoa,
pe.nomerazao,
seqfornecedor,
Representante,
decode( to_char(data_venda, 'MM'), 1, SUM(VLRVENDA)) as JANEIRO,
decode( to_char(data_venda, 'MM'), 1, SUM(NROITENS)) as QTDJAN,
decode( to_char(data_venda, 'MM'), 2, SUM(VLRVENDA)) as FEVEREIRO,
decode( to_char(data_venda, 'MM'), 2, SUM(NROITENS)) as QTDFEV,
decode( to_char(data_venda, 'MM'), 3, SUM(VLRVENDA)) as MARCO,
decode( to_char(data_venda, 'MM'), 3, SUM(NROITENS)) as QTDMAR,
decode( to_char(data_venda, 'MM'), 4, SUM(VLRVENDA)) as ABRIL,
decode( to_char(data_venda, 'MM'), 4, SUM(NROITENS)) as QTDABR,
decode( to_char(data_venda, 'MM'), 5, SUM(VLRVENDA)) as MAIO,
decode( to_char(data_venda, 'MM'), 5, SUM(NROITENS)) as QTDMAI,
decode( to_char(data_venda, 'MM'), 6, SUM(VLRVENDA)) as JUNHO,
decode( to_char(data_venda, 'MM'), 6, SUM(NROITENS)) as QTDJUN,
decode( to_char(data_venda, 'MM'), 7, SUM(VLRVENDA)) as JULHO,
decode( to_char(data_venda, 'MM'), 7, SUM(NROITENS)) as QTDJUL,
decode( to_char(data_venda, 'MM'), 8, SUM(VLRVENDA)) as AGOSTO,
decode( to_char(data_venda, 'MM'), 8, SUM(NROITENS)) as QTDAGO,
decode( to_char(data_venda, 'MM'), 9, SUM(VLRVENDA)) as SETEMBRO,
decode( to_char(data_venda, 'MM'), 9, SUM(NROITENS)) as QTDSET,
decode( to_char(data_venda, 'MM'), 10, SUM(VLRVENDA)) as OUTUBRO,
decode( to_char(data_venda, 'MM'), 10, SUM(NROITENS)) as QTDOUT,
decode( to_char(data_venda, 'MM'), 11, SUM(VLRVENDA)) as NOVEMBRO,
decode( to_char(data_venda, 'MM'), 11, SUM(NROITENS)) as QTDNOV,
decode( to_char(data_venda, 'MM'), 12, SUM(VLRVENDA)) as DEZEMBRO,
decode( to_char(data_venda, 'MM'), 12, SUM(NROITENS)) as QTDDEZ
from (select
j.nrorepresentante,
min( J.APELIDO ) as Representante,
p.seqpessoa,
p.nomerazao,
z.seqfornecedor,
J2.NOMERAZAO,
count( distinct V.SEQPRODUTO ) as NROITENS,
sum( ( ( case when 'N' in ( 'S', 'V' ) then V.VLRITEMSEMDESC else V.VLRITEM end ) - VLRICMSST - ( V.VLRDEVOLITEM - VLRDEVOLICMSST ))) as VLRVENDA,
V.DTAVDA as data_venda
from MRL_CUSTODIAFAM Y, MAXV_ABCDISTRIBBASE V, MAP_PRODUTO A, MAP_PRODUTO PB, MAP_FAMDIVISAO D,
MAP_FAMEMBALAGEM K, MAX_EMPRESA E, MAD_REPRESENTANTE J, GE_PESSOA P, GE_PESSOA J2, MRLV_DESCONTOREGRA RE, MAP_FAMFORNEC z
where D.SEQFAMILIA = A.SEQFAMILIA
and D.NRODIVISAO in (1)
and V.SEQPRODUTO = A.SEQPRODUTO
and V.SEQPRODUTOCUSTO = PB.SEQPRODUTO
and V.NROEMPRESA = 1
and V.NROSEGMENTO in ( 1,6,5,2,4,9,7,10,8,3 )
and V.NRODIVISAO = D.NRODIVISAO
and E.NROEMPRESA = V.NROEMPRESA
and z.seqfamilia = a.seqfamilia
and V.DTAVDA BETWEEN '01-JAN-2014' and '31-DEC-2014'
and Y.NROEMPRESA = nvl( E.NROEMPCUSTOABC, E.NROEMPRESA )
and Y.DTAENTRADASAIDA = V.DTAVDA
and K.SEQFAMILIA = A.SEQFAMILIA
and K.QTDEMBALAGEM = fPadraoEmbVenda2(D.SEQFAMILIA,'1')
AND V.SEQPRODUTO = RE.SEQPRODUTO(+)
AND V.DTAVDA = RE.DATAFATURAMENTO (+)
AND V.NRODOCTO = RE.NUMERODF (+)
AND V.SERIEDOCTO = RE.SERIEDF(+)
AND V.NROEMPRESA = RE.NROEMPRESA (+)
and Y.SEQFAMILIA = PB.SEQFAMILIA (+)
and V.NROREPRESENTANTE = J.NROREPRESENTANTE
AND Z.SEQFORNECEDOR = J2.SEQPESSOA
AND P.SEQPESSOA = 540
and V.SEQPESSOA = P.SEQPESSOA
and DECODE(V.TIPTABELA, 'S', V.CGOACMCOMPRAVENDA, V.ACMCOMPRAVENDA) in ( 'S', 'I' )
and exists ( select 1
from MAP_FAMFORNEC
where SEQFORNECEDOR = 277
and PRINCIPAL = 'S'
and MAP_FAMFORNEC.SEQFAMILIA = A.SEQFAMILIA )

group by J.NROREPRESENTANTE,p.nomerazao,p.seqpessoa,z.seqfornecedor,J2.NOMERAZAO,V.DTAVDA ) vendas, ge_pessoa pe
where trunc(data_venda) between '01-JAN-2014' and '31-DEC-2014'
AND SEQFORNECEDOR = 277
and vendas.seqpessoa = pe.seqpessoa
group by Representante,pe.seqpessoa,pe.nomerazao,seqfornecedor,NROITENS,data_venda) AAA, GE_PESSOA J3
WHERE AAA.SEQFORNECEDOR = J3.SEQPESSOA
group by AAA.seqpessoa,
AAA.nomerazao,
J3.NOMERAZAO,
seqfornecedor,
Representante
order by 4,1


Agradeço muito pela ajuda de todos, com certeza o que aprendi irá servir muito para vários outros casos que tenho!
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Gustavo, vc só precisa de um select de um subselect pra esse caso...
Não tem necessidade de incluir esses joins que vc incluiu
 
[...]
    ge_pessoa pe
where trunc(data_venda) between '01-JAN-2014' and '31-DEC-2014'
AND SEQFORNECEDOR = 277
and vendas.seqpessoa = pe.seqpessoa

Essas condições já estão definidas no subselect que está retornando com aliás vendas....
As colunas que vc precisa incluir, é só incluir no subselect pois vc já está utilizando a tabela GE_PESSOA no subselect. Então basta acrescentar os campos no subselect e incluir no group by...
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Quando você executa o select com o decode
decode( to_char(data_venda, 'MM'), 1, SUM(VLRVENDA)) as JANEIRO,
          decode( to_char(data_venda, 'MM'), 1, SUM(NROITENS)) as QTDJAN,

Nesse ponto já não totaliza o valor de vendas e o número de itens?
Tem mesmo nescessidade de fazer um SELECT novamente e aplicar o SUM nesses valores?

Estou questionando, pois logicamente, parece que vc está fazendo dois processamentos quando vc poderia fazer um só...
GOSTEI 0
Gustavo Silva

Gustavo Silva

03/10/2014

Olá Marisiana,

Desculpa se não entendi o seu questionamento, mas se entendi a resposta é a seguinte: O primeiro subselect ( from (select
j.nrorepresentante,
min( J.APELIDO ) as Representante,
p.seqpessoa...) é para gerar os valores!

O segundo (and exists ( select
1
from MAP_FAMFORNEC
where SEQFORNECEDOR = 277... é para buscar o código do fornecedor!

E o select principal é para retornar os resultados gerados no primeiro subselect, ou seja, os decode( to_char(data_venda, 'MM'), 1, SUM(VLRVENDA)) as JANEIRO... como vc sabe, está buscando as informações do subselect. Esta foi a única forma que encontrei de gerar os resultados, mas se tens outra forma, agradeço muito se informares como fazer.

Agradeço por sua atenção de apoio!
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Entendi... Na solução que vc postou não é a estrutura que eu alterei....
Você chegou a testar o exemplo que postei a cima?
GOSTEI 0
Gustavo Silva

Gustavo Silva

03/10/2014

Então, testei com o seu exemplo, no entanto as informações do representante amisterdã, retornam em linhas diferentes. Entendo que por haver representantes diferentes, obviamente deverá retornar os valores em linhas diferentes, no entanto o que precisava era exatamente que nos casos em que houvessem um único representante, as informações dos meses retornassem em uma única linha, daí então, fiz o teste com o código do Alex, fazendo algumas pequenas alterações para se adequar as minhas necessidades e deu certo.
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Ok... entendo!
Eu diria que simplifiquei o SQL que vc tinha, reestruturei e padronizei ele pra continuar fazendo a mesma coisa que o outro fazia.
A partir dali era só ver qual era a informação que estava fazendo aparecer em mais de uma linha...
Apresentei um código muito mais limpo, padronizado e de melhor compreensão, pois não se utiliza mais
AND V.DTAVDA = RE.DATAFATURAMENTO (+) 
utilizasse o padrão ANSI (left join, inner join, right join) pois evita joins errados e o Oracle trabalha muito melhor dessa forma.
Se vc observar melhor a solução que passei vai compreender melhor os questionamentos que fiz..
Sem mais...
GOSTEI 0
Gustavo Silva

Gustavo Silva

03/10/2014

Ok Marisiana,

Verifiquei as suas alterações e realmente estão no padrão que deve ser adotado, verifiquei também que a performance da execução melhora consideravelmente, no entanto, como eu precisava de uma solução imediata por ter um prazo a cumprir, utilizei o código do Alex para obter o resultado, mas tendo como meta estudar o seu código não só para aprender a utilizar o padrão correto, como também para que nos próximos códigos que eu precise criar, possa fazê-los da forma que você mostrou.

Por tudo agradeço-lhe muito e tenhas certeza que as suas informações foram e serão muito úteis, não só neste momento, por me ensinar algo que eu não sabia, como também no futuro!

Grande abraço e novamente obrigado! ;)
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

03/10/2014

Perfeito!
Fico feliz em ajudar!
Você tem em mãos o melhor SGBD que tem no mercado de trabalho, não deixe de explorar os recursos e de utilizá-los da melhor forma possível.

Bons estudos!
GOSTEI 1
POSTAR