Pular para o conteúdo
  • Este tópico contém 3 respostas, 2 vozes e foi atualizado pela última vez 7 anos, 8 meses atrás por Avatar photoJosé Laurindo Chiappa.
Visualizando 4 posts - 1 até 4 (de 4 do total)
  • Autor
    Posts
  • #108671
    DOUGLASD
    Participante

      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) –> OK

      SE 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

      #108672
      Avatar photoJosé Laurindo Chiappa
      Moderador

        Colega, 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”…

        #108673
        DOUGLASD
        Participante

          Bom 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 FINAL

          ELE 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.

          #108674
          Avatar photoJosé Laurindo Chiappa
          Moderador

            Bem, 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, 300

            SQL>

            ===> 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, 300

            SQL>

            ===>>> 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

          Visualizando 4 posts - 1 até 4 (de 4 do total)
          • Você deve fazer login para responder a este tópico.
          plugins premium WordPress