Autor Tópico: Ajuda com select complicado (RESOLVIDO)  (Lida 3000 vezes)

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Ajuda com select complicado (RESOLVIDO)
« Online: Junho 04, 2012, 04:26:20 am »
Pessoal, se possível, gostaria de uma força com um select um pouco complicado que preciso montar:

São 4 tabelas envolvidas:
campanhas (numero, data_inicial, data_final)
pedidos (numero, data)
produtos_vendidos_no_pedido (pedido, produto, qtde)
produtos_devolvidos_no_pedido (pedido, produto, qtde)

Eu preciso passar, de preferência, apenas o número da campanha como parâmetro.
A saída do select tem que ser esta:
Produto, qtde_vendida, qtde_devolvida (Agrupando por produto e totalizando as 2 qtdes)

A ideia é listar sumarizadamente todos os produtos vendidos e devolvidos que constam nos pedidos cuja data se encaixe entre as datas da campanha fornecida como parâmetro.

Já dei nó nos miolos e ainda não consegui.

Alguém fera no assunto poderia ajudar?

Grato.
Rodrigo
« Última modificação: Junho 04, 2012, 01:54:34 pm por rrma »
Rodrigo Araújo

Haroldo

  • Expert
  • *****
  • Mensagens: 6264
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Ajuda com select complicado
« Responder #1 Online: Junho 04, 2012, 08:26:56 am »
Nào da para testar sem ter as tabelas populadas.Eu criaria uma stored procedure alimentando uma tabela temporária.
Código: [Selecionar]

SELECT
  PV.PRODUTO
  SUM(PV.QTDE_VENDIDA),
  SUM(PD.QTDE_DEVOLVIDA)

FROM
  PEDIDO P
    INNER JOIN PRODUTOS_VENDIDOS PV     ON PV.PEDIDO=P.NUMERO
    INNER JOIN PRODUTOS_DEVOLVIDOS PD ON PD.PEDIDO=P.NUMERO

WHERE
  P.DATA >= (SELECT DATA_INICIAL FROM CAMPANHA WHERE NUMERO=[CAMPANHA])
  AND P.DATA <=(SELECT DATA_FINAL FROM CAMPANHA WHERE NUMERO=[CAMPANHA])}

GROUP BY
  PV.PRODUTO

« Última modificação: Junho 04, 2012, 12:17:13 pm por Haroldo »

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Re:Ajuda com select complicado
« Responder #2 Online: Junho 04, 2012, 11:59:09 am »
Haroldo, primeiramente obrigado pela resposta tão rápida.

Eu testei a query e deu uma pequena diferença nos valores, contando manualmente as qtdes. Como são poucos registros dá pra contar manual pra conferir.
Adaptando a query para o nome real dos campos ficou assim:

SELECT PV.produto, SUM( PV.qtde ) , SUM( PD.qtde )
FROM pedidos P
INNER JOIN pedidos_itens_atuais PV ON PV.pedido = P.pedido
INNER JOIN pedidos_itens_devolvidos PD ON PD.PEDIDO = P.pedido
WHERE P.data_pedido >= ( SELECT data_inicial FROM campanhas WHERE numero = [campanha] )
AND P.data_pedido <= ( SELECT data_final FROM campanhas WHERE numero = [campanha] )
GROUP BY PV.produto

A questão é que nem sempre todos os produtos constantes na tabela de produtos vendidos (pedidos_itens_atuais) estão também na tabela de produtos devolvidos (pedidos_itens_devolvidos). Acho que por isso a somatória ficou diferente.
Talvez eu tenha que usar uma quinta tabela (tabela de produtos) pra ter certeza de que todos os produtos foram lidos, algo assim.

Na minha contagem manual ficou assim:
Produto/Vendidos/Devolvidos
1   57   24
2   67   48
3   31   1
4   14   5

Pela query ficou assim:
produto   SUM( PV.qtde )   SUM( PD.qtde )
1   80   43
2   64   36
3   35   67
4   29   51

De qq forma já serviu como ponto de partida até pra estudo meu de como funciona o inner join, pois não tem jeito de eu aprender esse troço.
Caso tenha algum tempo e possibilidade de dar uma nova olhada, postei o dump das tabelas aqui: http://www.softideias.com/clarajoias/sql.txt. As contagens que citei acima se referem a campanha de número 4.

Muito obrigado mesmo.
Rodrigo
Rodrigo Araújo

Haroldo

  • Expert
  • *****
  • Mensagens: 6264
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Ajuda com select complicado
« Responder #3 Online: Junho 04, 2012, 12:19:49 pm »
Este procedimento vai ser rotineiro ou esporádico?

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Re:Ajuda com select complicado
« Responder #4 Online: Junho 04, 2012, 12:21:11 pm »
É uma consulta que vai ser realizada praticamente uma vez por mês, no final da campanha de vendas.
Rodrigo Araújo

Haroldo

  • Expert
  • *****
  • Mensagens: 6264
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Ajuda com select complicado
« Responder #5 Online: Junho 04, 2012, 12:29:10 pm »
Código: [Selecionar]
SELECT PV.produto as produto , SUM( PV.qtde )  as vendido , 0 as devolvido
FROM pedidos P
INNER JOIN pedidos_itens_atuais PV ON PV.pedido = P.pedido
WHERE P.data_pedido >= ( SELECT data_inicial FROM campanhas WHERE numero = [campanha] )
AND P.data_pedido <= ( SELECT data_final FROM campanhas WHERE numero = [campanha] )
UNION ALL
SELECT PD.produto as produto , 0 as vendido ,  SUM( PD.qtde )  as devolvido
FROM pedidos P
INNER JOIN pedidos_itens_devolvidos PD ON PD.PEDIDO = P.pedido
WHERE P.data_pedido >= ( SELECT data_inicial FROM campanhas WHERE numero = [campanha] )
AND P.data_pedido <= ( SELECT data_final FROM campanhas WHERE numero = [campanha] )
GROUP BY PV.produto

Haroldo

  • Expert
  • *****
  • Mensagens: 6264
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Ajuda com select complicado
« Responder #6 Online: Junho 04, 2012, 12:30:27 pm »
tenta assim, se não der vamos criar uma view com esse código sem  o group by.
e fazer o select em cima da view.

Haroldo

  • Expert
  • *****
  • Mensagens: 6264
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Ajuda com select complicado
« Responder #7 Online: Junho 04, 2012, 12:32:53 pm »
 nesse caso é rotineira, temos que desenvolver algo definitivo.

É uma consulta que vai ser realizada praticamente uma vez por mês, no final da campanha de vendas.

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Re:Ajuda com select complicado
« Responder #8 Online: Junho 04, 2012, 12:39:07 pm »
Haroldo, com a última query deu o seguinte erro no phpmyadmin:
#1054 - Unknown column 'PV.produto' in 'group statement'

Acredito que o group by dá erro pq PV.produto só existe no primeiro select do UNION, no segundo ele se chama PD.produto.

Nesse meio tempo, fiz em paralelo uma tabela temporária e meio que preenchi a contagem via apl blank, funcionou belezinha.
Como vc queria criar uma view, acho que acabei optando por uma solução parecida, só que via blank.

De qq forma achei a query interessante pra estudo.

Muito obrigado mesmo pelo empenho na solução.
Rodrigo
Rodrigo Araújo

Haroldo

  • Expert
  • *****
  • Mensagens: 6264
  • Conhecimento diminui limitações.△TFA△
    • Infinitus Web Gestão Empresarial/Gestão ITIL/Consultoria Scriptcase
Re:Ajuda com select complicado
« Responder #9 Online: Junho 04, 2012, 12:47:09 pm »
tente trocar PV.produto por produto apenas.

Cleyton Euler

  • Expert
  • *****
  • Mensagens: 1149
    • Associação de Usuários Scriptcase
    • Email
Re:Ajuda com select complicado
« Responder #10 Online: Junho 04, 2012, 12:49:33 pm »
Seguindo o raciocínio do mestre Haroldo:

SELECT PV.produto, SUM( PV.qtde )
FROM pedidos P
INNER JOIN pedidos_itens_atuais PV ON PV.pedido = P.pedido
WHERE P.data_pedido >= ( SELECT data_inicial FROM campanhas WHERE numero = 4 )
AND P.data_pedido <= ( SELECT data_final FROM campanhas WHERE numero = 4 )
GROUP BY PV.produto
UNION ALL
SELECT PD.produto, SUM( PD.qtde )
FROM pedidos P
INNER JOIN pedidos_itens_devolvidos PD ON PD.pedido = P.pedido
WHERE P.data_pedido >= ( SELECT data_inicial FROM campanhas WHERE numero = 4 )
AND P.data_pedido <= ( SELECT data_final FROM campanhas WHERE numero = 4 )
GROUP BY PD.produto

Está query está contando de acordo com sua contagem manual, com o detalhe de mostrar o agrupamento abaixo do outro e não ao lado.
Associação de Usuários Scriptcase
http://www.auscriptcase.com.br

Consultoria Scriptcase Versão 5
http://www.infinitusweb.com.br

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Re:Ajuda com select complicado
« Responder #11 Online: Junho 04, 2012, 12:50:55 pm »
Haroldo, fiz uma pequena mudança na sua query, adicionando um group by em cada select do union:

SELECT PV.produto AS produto, SUM( PV.qtde ) AS vendido, 0 AS devolvido
FROM pedidos P
INNER JOIN pedidos_itens_atuais PV ON PV.pedido = P.pedido
WHERE P.data_pedido >= (
SELECT data_inicial
FROM campanhas
WHERE numero =4 )
AND P.data_pedido <= (
SELECT data_final
FROM campanhas
WHERE numero =4 )
GROUP BY PV.produto
UNION ALL
SELECT PD.produto AS produto, 0 AS vendido, SUM( PD.qtde ) AS devolvido
FROM pedidos P
INNER JOIN pedidos_itens_devolvidos PD ON PD.PEDIDO = P.pedido
WHERE P.data_pedido >= (
SELECT data_inicial
FROM campanhas
WHERE numero =4 )
AND P.data_pedido <= (
SELECT data_final
FROM campanhas
WHERE numero =4 )
GROUP BY PD.produto

A contagem bateu 100%, só que vendidos e devolvidos ficaram em blocos separados:

produto   vendido   devolvido
1   57   0
2   67   0
3   31   0
4   14   0
1   0   24
2   0   48
3   0   1
4   0   5
5   0   6

O lance agora era juntar os 2 blocos num bloco só.

Se eu tentar o group by único no final usando "GROUP BY" produto, ele soma as qtdes vendidas e totaliza no ultimo produto:
produto   vendido   devolvido
4   169   0
1   0   24
2   0   48
3   0   1
4   0   5
5   0   6
Rodrigo Araújo

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Re:Ajuda com select complicado
« Responder #12 Online: Junho 04, 2012, 12:54:44 pm »
Cleyton, foi exatamente o que fiz.
Pensando melhor, acho que dessa forma um grid com quebra totalizada por produto já resolve o problema né?

Concorda Haroldo?
Rodrigo Araújo

Cleyton Euler

  • Expert
  • *****
  • Mensagens: 1149
    • Associação de Usuários Scriptcase
    • Email
Re:Ajuda com select complicado
« Responder #13 Online: Junho 04, 2012, 01:14:11 pm »
O caminho acho que é por aqui:

SELECT pedidos_itens_atuais.produto, (SELECT SUM( qtde ) FROM pedidos_itens_atuais WHERE pedido = pedido) AS Vendido, (SELECT SUM( qtde ) FROM pedidos_itens_devolvidos WHERE pedido = pedido) AS devolvido
FROM pedidos_itens_atuais, pedidos_itens_devolvidos, pedidos
WHERE data_pedido >= ( SELECT data_inicial FROM campanhas WHERE numero = 4 )
AND data_pedido <= ( SELECT data_final FROM campanhas WHERE numero = 4 )
GROUP BY produto

Está agrupando, agora é ajeitar para contar corretamente. algo me diz que o pulo do gato está nas cláusulas where das subselects.
Associação de Usuários Scriptcase
http://www.auscriptcase.com.br

Consultoria Scriptcase Versão 5
http://www.infinitusweb.com.br

rrma

  • Global Moderator
  • Expert
  • *****
  • Mensagens: 816
  • Quem com porcos se mistura tanto bate até que fura
    • Email
Re:Ajuda com select complicado
« Responder #14 Online: Junho 04, 2012, 01:40:42 pm »
Cleyton, não ficou legal não, olha o resultado:

produto   Vendido   devolvido
1   323   98
2   323   98
3   323   98
4   323   98
5   323   98
16   323   98

Apareceu até um produto que não foi vendido nem devolvido.
Acho que o resultado do penúltimo post meu ficou melhor, veja lá.
Rodrigo Araújo