Jump to content
Lucas S. Rosa

SQL que Retorna o produto mais vendido em um determinado periodo

Recommended Posts

Olá pessoal tudo bem?

 

É o seguinte estou tentando fazer um script em SQL no Oracle que retorna o "código, nome, valor total vendido" do produto mais vendido em um determinado período.

Fiz o script, mas ele tá retornando como resultado todos os produtos vendido no período, e o que eu gostaria era que ele apenas me retorna o produto mais vendido. Eu coloquei a função agregada MAX(...), mas mesmo assim é retornado todos os produtos vendido no período, segue meu script.(OBS: ele tá funcionando, o problema é que não está retornando apenas o produto mais vendido, mas todos os produtos vendidos).

 

SELECT SUB.SUB_CODIGO, SUB.SUB_NOME, MAX(TESTE.TOTAL) FROM SUBSTANCIA SUB
  INNER JOIN
    (SELECT ITENS.SUB_CODIGO, SUM(ITENS.ITEM_NOT_SAI_QTDE * ITENS.ITEM_NOT_SAI_PRECO) AS TOTAL
       FROM ITENS_NOTA_SAIDA ITENS INNER JOIN NOTA_SAIDA NOTA ON
         NOTA.NOT_SAI_CODIGO = ITENS.NOT_SAI_CODIGO  
           WHERE NOT_SAI_DATA BETWEEN '17/03/2017' AND '17/03/2017'
             GROUP BY ITENS.SUB_CODIGO
    ) TESTE
  ON (SUB.SUB_CODIGO = TESTE.SUB_CODIGO)
    GROUP BY SUB.SUB_CODIGO, SUB.SUB_NOME;

Em anexo tá o resultado que esta retornando pra vocês terem uma ideia do que eu to falando.

Se alguém poder me ajudar eu agradeço.

resultado_sql.pdf

Share this post


Link to post
Share on other sites

Utilize Analytic Functions

 

por exemplo RANK

 

RANK

The RANK analytic function assigns a sequential rank for each distinct value in the specified window.

SELECT val
FROM   (SELECT val,
               RANK() OVER (ORDER BY val DESC) AS val_rank 
        FROM   rownum_order_test)
WHERE  val_rank <= 5;

       VAL
----------
        10
        10
         9
         9
         8
         8

 

Fonte

Share this post


Link to post
Share on other sites

Limite para apenas um resultado. Depende da versão do oracle, pode-se usar ROWNUM ou ROWLIMIT (12c R1 - 12.1).

 

ROWNUM

SELECT * FROM
(/** sub-select **/)
WHERE ROWNUM = 1;

 

ROWLIMIT:

SELECT * FROM
(/** sub select **/)
FETCH FIRST ROW ONLY

http://stackoverflow.com/questions/42862903/transform-static-array-into-a-generated-by-foreach-loop

http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html

  • +1 1

Share this post


Link to post
Share on other sites

Deve ser isto

 

SELECT *
FROM
(
SELECT ITENS.SUB_CODIGO
       RANK() OVER (PARTITION BY deptno ORDER BY TOTAL DESC) rank
FROM   (SELECT ITENS.SUB_CODIGO,
               SUM(ITENS.ITEM_NOT_SAI_QTDE * ITENS.ITEM_NOT_SAI_PRECO) AS TOTAL
        FROM ITENS_NOTA_SAIDA ITENS INNER JOIN NOTA_SAIDA NOTA ON
        NOTA.NOT_SAI_CODIGO = ITENS.NOT_SAI_CODIGO  
        WHERE NOT_SAI_DATA BETWEEN '17/03/2017' AND '17/03/2017')
) WHERE RANK = 1   

Share this post


Link to post
Share on other sites

Boa tarde o que você necessita é utilizar o ROWNUM conforme mencionado pelo amigo Gabriel Heming, onde o comando ficaria desta forma:

 

SELECT SUB.SUB_CODIGO, SUB.SUB_NOME, MAX(TESTE.TOTAL) FROM SUBSTANCIA SUB
  INNER JOIN
    (SELECT ITENS.SUB_CODIGO, SUM(ITENS.ITEM_NOT_SAI_QTDE * ITENS.ITEM_NOT_SAI_PRECO) AS TOTAL
       FROM ITENS_NOTA_SAIDA ITENS INNER JOIN NOTA_SAIDA NOTA ON
         NOTA.NOT_SAI_CODIGO = ITENS.NOT_SAI_CODIGO  
           WHERE NOT_SAI_DATA BETWEEN '17/03/2017' AND '17/03/2017'
             GROUP BY ITENS.SUB_CODIGO
    ) TESTE
  ON (SUB.SUB_CODIGO = TESTE.SUB_CODIGO)
    GROUP BY SUB.SUB_CODIGO, SUB.SUB_NOME
    AND ROWNUM = 1;

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By MarcosAntonio
      Boa tarde !
      estou carregando um arquivo texto numa variável BLOB e preciso manipular em loop, para ler linha a linha e aplicar os SUBSTRs para inserir no banco, mas não sei como fazer o loop, a interação entre as linhas e quando saber o momento de sair do loop, alguém pode me ajudar?

      ex do conteúdo do BLOB:
       
      2AAA02012021123421
      2AAA02012021213453
      2AAA02012021105413
       
      quero por exemplo retirar a informação da linha 2 a partir do quarto caracter e parando no decimo segundo caracteres
    • By Motta
      Oracle is moving its headquarters from Silicon Valley to Austin, Texas
    • By Thiago Btos
      Boa tarde galera.
       
      Fiz um select que tras 4 informações do banco (matricula, nome, data e hora)
      SELECT QD1_MAT, RA_NOME, QD1_DTBAIX AS DATA, QD1_HRBAIX FROM QD1010 QD1 INNER JOIN SRA010 SRA ON RA_MAT = SUBSTR(QD1_MAT, 5) AND SRA.D_E_L_E_T_ <> '*' ORDER BY QD1_DTBAIX, QD1_HRBAIX Retornando os seguintes registros:

       
       
       
      Preciso retornar somente as linhas em amarelo, que seria a seguinte condição.
      Caso tiver alguma matricula igual, trazer somente o registro com a maior data, junto com seu respectivo horário.
       
       
      O mais próximo que consegui chegar foi utilizando o MAX para data e hora, e agrupando o restante dos campos.
      SELECT QD1_MAT,RA_NOME,MAX(DATA), MAX(QD1_HRBAIX) FROM ( SELECT QD1_MAT, RA_NOME, QD1_DTBAIX AS DATA, QD1_HRBAIX FROM QD1010 QD1 INNER JOIN SRA010 SRA ON RA_MAT = SUBSTR(QD1_MAT, 5) AND SRA.D_E_L_E_T_ <> '*' ) GROUP BY QD1_MAT,RA_NOME Porém na hora ele não pega o valor correspondente e sim o valor máximo.

       
       
      Ai estou travado nessa parte, como faço para trazer a hora corresponde sem o restante dos registros?
    • By mr22robot
      Boa tarde. Estou com o seguinte problema: Preciso retornar um selct da seguinte maneira:
      exemplo que não funciona:
      select codusur,numnota,codcli,cliente,vltotal,numtransvenda,dev,decode(vlvenda),if(vlvenda > 100 then 1 else 2) from( select tb1.codusur,tb1.numnota,tb1.codcli,tb1.cliente,tb1.vltotal,tb1.numtransvenda,DECODE(tb2.VLTOTAL,NULL,0,tb2.VLTOTAL)DEV from( select codusur,numnota,pcnfsaid.codcli,pcnfsaid.cliente,pcnfsaid.vltotal,pcnfsaid.numtransvenda from pcnfsaid where pcnfsaid.dtsaida > '01-OCT-2020' and pcnfsaid.dtcancel is null )tb1 left outer join (select DISTINCT VLTOTAL,VW_INTEGRA_DEVOLUCAO_TOTAL.NUMTRANSVENDA from VW_INTEGRA_DEVOLUCAO_TOTAL )tb2 on tb1.NUMTRANSVENDA = tb2.NUMTRANSVENDA order by numnota ) Como pode reparar, eu usei um if/else já que não sei a forma correta de usar. Pois com DECODE não consegui usar uma forma de fazer a comparação. 
      Pois preciso mesmo retornar uns valores fixos. Ex: 
      Se o valor > 40000, retorna um valor x; Se for maior que 5000 retorna um valor y. 
      Aguardo a ajuda dos amigos. Grato
    • By MarcosAntonio
      boa tarde. 
      Estou precisando de um Select que retorne uma soma que ao chegar a determinado valor ela reinicie e continue fazendo sucessivamente
       select   pedido,   volume,   limite,   SUM(volume) over (order by pedido ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) saldo   from pedidos  group by pedido o select está retornando assim porém quero que toda vez que chegue ou passe do limite resete o saldo, por exemplo parar no 100 que é o limite e começar um novo saldo
      pedido     volume    limite    saldo  1             70            100        70  2             10            100        80  3             20            100        100  4             50            100        150  5             30            100        180  
      preciso que ele soma o volume enquanto o saldo seja <= que o "limite", quando passar pare de somar e comece outra soma começando do 0, como no exemplo abaixo.
      pedido    volume    limite    saldo  1             70            100        70  2             10            100        80  3             20            100        100  4             50            100        50  5             30            100        80  
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.