- Este tópico contém 3 respostas, 2 vozes e foi atualizado pela última vez 7 anos, 8 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
29 de março de 2017 às 10:15 pm #108671DOUGLASDParticipante
Boa tarde galera,
Preciso fazer uma SQL onde vou buscar vários pedidos de um único cliente, mas com a condição de trazer apenas os pedidos que tenham produtos em conjunto;
EXEMPLO
PRECISO SELECIONAR TODOS OS PEDIDOS DO CLIENTE ‘FULANO’
MAS SÓ QUERO VISUALIZAR OS PEDIDOS QUE POSSUEM UM COMBO 1 ONDE TENHAM(AÇUCAR, ARROZ, FEIJÃO) OU OUTRO COMBO 2 ONDE TENHAM (AÇUCAR, SAL, FARINHA).
NA FALTA DE UM ITEM EU NAO QUERO O PEDIDO, OU COM ITENS TROCADOS TB NÃO PODE CONSIDERAR.
PEDIDO 001 PRODUTO (ACUCAR, SAL, FARINHA) –> OK
PEDIDO 002 PRODUTO (ACUCAR, SAL) –> NÃO
PEDIDO 003 PRODUTO (ACUCAR, ARROZ, FARINHA) –> NÃO
PEDIDO 004 PRODUTO (ACUCAR, ARROZ, FEIJAO) –> OKSE ESSES FOSSEM OS DADOS EU TERIA 02 PEDIDOS VISUALIZADOS.
Já tentei de tudo, mas acho que está me faltando a lógica.
Obrigado a todos
30 de março de 2017 às 1:02 am #108672José Laurindo ChiappaModeradorColega, sorry mas nos falta a sua ** modelagem ** aí, nós precisaríamos saber EXATAMENTE como fica registrado um Pedido e os itens do pedido… IGUALMENTE, vc não diz a versão do seu database mas vou SUPOR aqui 11G, que é uma relativamente recente…
Muito bem : SE vc estiver usando a modelagem tradicional para esses casos, onde para cada pedido é inserido um registro na tabela PEDIDO e N registros na tabela ITEM_PEDIDO (um registro pra cada item), entre outras maneiras vc poderia fazer um PIVOT (transformando as N linhas de cada pedido numa linha só, concatenando os produtos numa nova coluna PRODUTOS_DO_PEDIDO), e depois simplesmente mandar um SELECT colunas FROM tabeladeitensdepedidos WHERE PRODUTOS_DO_PEDIDO = ‘ACUCAR, SAL, FARINHA’ OR PRODUTOS_DO_PEDIDO = ‘ACUCAR, ARROZ, FEIJAO’, veja http://www.oratable.com/pivot-in-oracle-11g-to-select-rows-as-columns/ como um exemplo….
Outra possibilidade é vc Agrupar por Pedido (com Analytics) , e aí pedir para fazer a comparação do valor agregado via stragg ou similar, veja http://stackoverflow.com/questions/468990/how-can-i-combine-multiple-rows-into-a-comma-delimited-list-in-oracle para exemplo…
Dá uma ** boa ** estudada nos links que te passei, e se tiver dúvidas na implementação PLZ nos manda o CREATE TABLE das tabelas e uns INSERTs pra colocar uns poucos dados nas tabelas E nos mostra mais ou menos o que vc estava fazendo, que podemos palpitar mais….
[]s
Chiappa
OBS :
um ponto *** CRUCIAL *** para a resposta, que vc não diz mas pode COMPLICAR enormemente ou simplificar, é se a SEQUÊNCIA que vc quer é fixa ou não, ie : se eu tiver um Pedido com os itens FEIJÃO, AÇUCAR, ARROZ e outro com ARROZ, AÇUCAR, FEIJÃO eles TEM que aparecer ou não, é somente aqueles pedidos na exata sequência AÇUCAR, ARROZ, FEIJÃO ??? Pois se vc for usar algum tipo de Pivot, LOGICAMENTE a string “FEIJÃO, AÇUCAR, ARROZ” é Completamente Diferente da string “AÇUCAR, ARROZ, FEIJÃO”…
30 de março de 2017 às 3:31 pm #108673DOUGLASDParticipanteBom dia meu amigo,
Em primeiro lugar obrigado pela atenção.
Caro amigo as tabelas que vou usar só não preciso do cabeçalho do pedido.
Seria mais ou menos assim.
TABELA ITENS DO PEDIDO (TBPEDITEM) COLUNAS CODCLI, CODPROD, NUMNOTA, DTPEDIDO
TABELA PRODUTO (TPPRODUTO) COLUNAS CODPROD, DESCRICAO
TENHO COMO REGRA DUAS CESTAS DE PRODUTOS CONJUGADOS, NÃO IMPORTA A ORDEM, PORQUE ELES PODEM ESTAR EM PEDIDOS DIFERENTES, APENAS A EMPRESA QUER SABER SE O MESMO CLIENTE COMPROU ESSES PRODUTOS EM UM CERTO PERÍODO, NÃO PRECISA ESTAR NO MESMO PEDIDO.
OPÇÃO 1 -> CODPROD IN(100,200,300)
OPÇÃO 2 ->CODPROD IN(100,400,500)
PRECISO REALIZAR UM SELECT ONDE EU BUSCO OS PEDIDOS DE UM DETERMINADO PERIODO BETWEEN (DTPEDIDO) DE UM DETERMINADO CLIENTE (CODCLI) E QUE POSSA ME TRAZER APENAS SE O CONJUNTO DE PEDIDOS TIVER EXATAMENTE A OPÇÃO 1 OU A OPÇÃO 2 NOS PRODUTOS (CODPROD)
O RESULTADO SERIA ALGO ASSIM;
DTPEDIDO, CODCLI, NUMNOTA + RESULTADO CODPROD
01/03/2017, 5501, 455444, SE OPÇÃO 1 ‘CESTA 1 VENDIDA’ (COMO UM CASE OU DECODE) SE OPÇÃO 2 ‘CESTA 2 VENDIDA’ ELSE ‘NADA ENCONTRADO’.
NO FINALELE TERIA QUE VERIFICAR SE DENTRO DE TODOS OS PEDIDOS EU TENHO A OPÇÃO 1 OPÇÃO 2 OU AINDA NENHUMA.
OBS. O QUE EU NÃO SEI,É COMO FAZER PARA QUE O SQL TRAGA EXATAMENTE O QUE ESTÁ NA OPÇÃO DE PRODUTOS, NÃO PODE SER DIFERENTE. A EMPRESA PRECISA SABER SE DETERMINADO CLIENTE COMPROU A OPÇAO 1 OU 2 EM UM DETERMINADO PERÍODO
JÁ TENTEI AS CONDIÇÕES ALL, IN, EXISTS…. MAS ME FALTOU A LÓGICA.
Grande abraço.
30 de março de 2017 às 5:30 pm #108674José Laurindo ChiappaModeradorBem, primeiro antes de mais nada, não teria como vc EVITAR ESCREVER APENAS EM MAÍSUCULAS ??? Fica ** muito Ruim ** de ler, dá a impressão que vc está GRITANDO….
Segunda coisa, como eu disse facilitaria Muito também os CREATE TABLE e uns INSERTs pra gente tentar montar um caso de teste… E finalmente, para o seu crescimento como Programador, seria Mais do que bom se vc tivesse lido os links que passei, estudado um pouco e depois nos mostrasse a lógica que vc tentou montar : criticando/apontando os pontos corretos ou não da sua lógica vc aprenderia muito mais…..Mas okdoc, vou tentar montar algo : no meu caso vou usar Oracle Express Edition 11gR2, como vc Não Diz qual é a sua versão sei lá se a solução que monateri vai ser compatível com o que vc tem – se não sabia, fique sabendo que nem todos os recursos do database Oracle foram introduzidos desde a primeira versão, não é impossível que algum recurso que eu use tenha sido introduzido em versão POSTERIOR a que vc tem…
Segue :
SQL> CREATE TABLE TBPEDITEM (CODCLI number,
2 NUMNOTA number,
3 CODPROD number,
4 DTPEDIDO date
5 );Tabela criada.
SQL> INSERT INTO TBPEDITEM values (1, 1000, 100, to_date(’30/03/2017′, ‘dd/mm/yyyy’));
1 linha criada.
SQL> INSERT INTO TBPEDITEM values (1, 1000, 200, to_date(’30/03/2017′, ‘dd/mm/yyyy’));
1 linha criada.
SQL> INSERT INTO TBPEDITEM values (1, 2000, 200, to_date(’01/04/2017′, ‘dd/mm/yyyy’));
1 linha criada.
SQL> INSERT INTO TBPEDITEM values (1, 2000, 100, to_date(’01/04/2017′, ‘dd/mm/yyyy’));
1 linha criada.
SQL> INSERT INTO TBPEDITEM values (1, 2000, 300, to_date(’01/04/2017′, ‘dd/mm/yyyy’));
1 linha criada.
SQL>
Agora a lógica : um IN significa membro de grupo, ie, se o registro atual é OU a opção a OU a opção B ou a opção C da sua lista – vc mesmo disse porém que NÂO É ISSO que vc precisa, vc quer que dentro de um pedido o ** primeiro ** registro seja CODPROD=100 e o segundo registro desse mesmo pedido seja CODPROD=200 e o terceiro registro seja 300, então vc quer fazer uma comparação ao mesmo tempo com *** TODOS *** os registros de um Pedido, não só o registro atualmente sendo lido que é o que o IN faz….
Há ** trocentas ** maneiras de se fazer isso, como eu disse, uma delas é vc Pivotar, ie, transformar :NUMNOTA CODPROD
10 100
10 200
10 300
…
nisto :NUMNOTA PEDIDOS_DA_NOTA
10 100,200,300
…==> Uma das n opções para isso é a LISTAGG, *** SE *** a sua versão de banco for 11gR2 :
SQL> SELECT NUMNOTA, LISTAGG(CODPROD, ‘, ‘) WITHIN GROUP (ORDER BY CODPROD) as PEDIDOS_DA_NOTA
2 FROM TBPEDITEM
3* GROUP BY NUMNOTA;NUMNOTA PEDIDOS_DA_NOTA
———- ———————————–
1000 100, 200
2000 100, 200, 300SQL>
===> Pronto : agora é super-simples vc aplicar a condição de filtro que quiser nessa coluna ‘inventada’ PEDIDOS_DA_NOTA, inclusive PEDIDOS_DA_NOTA=’100,200,300′ que vc quer – a única coisa é que, como essa coluna NÂO EXISTE na tabela original mas sim só no resultset gerado pela consulta, vc TEM que usar o RESULTSET como origem de dados, assim :
SQL> SELECT * FROM
2 (SELECT NUMNOTA, LISTAGG(CODPROD, ‘, ‘) WITHIN GROUP (ORDER BY CODPROD) as PEDIDOS_DA_NOTA
3 FROM TBPEDITEM
4 GROUP BY NUMNOTA)
5 WHERE PEDIDOS_DA_NOTA = ‘100, 200, 300’;NUMNOTA PEDIDOS_DA_NOTA
———- ———————————–
2000 100, 200, 300SQL>
===>>> Sacou ???? Logicamente :
a) é TRIVIAL vc incluir outras condições de filtragem na query que gera o resultset, como o DTPEDIDO BETWEEN nãoseioque que vc citou que precisa
b) isto é só um EXEMPLO SIMPLES de ** uma ** das técnicas que vc pode Aplicar pra chegar no que vc quer, que é filtrar por *** TODOS *** os N produtos constantes na NOTAFISCAL/PEDIDO : de forma ALGUMA está é a melhor técnica, nem a que melhor se aplica às suas necessidades, é só um pequeno Exemplo…
Fica agora POR TUA CONTA estudar a Documentação e os links que providenciei para se aprofundar nos detalhes desta e das OUTRAS técnicas possíveis, para poder escolher a melhor pro SEU caso, com os SEUS dados, na SUA versão de banco, etc…[]s
Chiappa
-
AutorPosts
- Você deve fazer login para responder a este tópico.