Dúvida em query com GROUP BY

Estou utilizando o Hibernate, e tenho a seguinte query para listar todos os produtos que foram vendidos (com os somatórios de quantidade e valor):

SELECT SUM(i.item_qtd) as qtd_total, SUM(i.item_valor_total) as valor_total, i.item_descricao, i.prod_referencia, cliente.cli_codigo, cliente.cli_nome from item_venda as i INNER JOIN venda as venda ON i.venda = venda.vend_codigo INNER JOIN cliente as cliente ON pedido.cliente = cliente.cli_codigo GROUP BY cliente.cli_codigo, i.prod_codigo

O resultado é agrupado da seguinte maneira:

Porém, gostaria de permitir a ordenação pela quantidade de itens vendidos para cada cliente.

Pensei em incluir na query:

Mas os produtos ficam ordenados assim(considera cada agrupamento do item):

E quanto vou fazer o agrupamento(grupo no ireport) no relatório fica “dividido” os clientes:

[quote]Cliente A
Produto B | qtd = 25 | valor = 2.500

Cliente B
Produto A | qtd = 15 | valor = 1.500

Cliente A
Produto A | qtd = 11 | valor = 1.100[/quote]

Tenho como fazer um ORDER BY considerando o somatório de todos os produtos vendidos por cliente. ex:

Cliente A comprou 36 unidades, Cliente B comprou 15 unidades.

Então primeiro pego todos os produtos do Cliente A:

[quote]
Cliente A | Produto B | qtd = 25 | valor = 2.500
Cliente A | Produto A | qtd = 11 | valor = 1.100[/quote]

E depois pego os produtos do Cliente B:

É possível fazer isso? Talvez com o subselect do Hibernate?

vc qr q agrupe os Cliente A para depois os Clientes B
é isso?

Também tentei desse modo, no entanto se eu ordenar dessa maneira ele primeiro ordena por nome, e só irá ordenar pela qtd quando o nome é igual.

Ficaria assim:

Se fosse na situação acima perfeito, mas por exemplo:

Nesse caso, primeiro ordena pelo nome do cliente e depois pelas quantidades.Só que o cliente C é o que mais comprou deveria ser o primeiro da lista.Mas a primeira ordenação leva em consideração o nome, então ele ficou por último.

Nesse caso acima eu poderia colocar para ordenar pela qtd (desse modo o cliente C seria o primeiro da lista).No entanto, os clientes não ficariam agrupados

removendo o cod produto do group by, e ordenando por qtde desc vc consegue uma view proxima do que vc esta querendo

deve ter maneiras mais simples (principalmente utilizando features do banco que usa , vai depender do banco), mas acredito que você precise ir montando os valores em partes pra chegar onde quer…

você quer ordernar por clientes com maior quantidade de vendas (em geral) e depois pelas quantidades por produto…

a primeira coisa que faria, seria calcular os totais por produto…

    SELECT 
      v.cliente, 
      iv.produto, 
      sum(iv.qtd) qtd_total, 
      sum(iv.valor) valor_total
    FROM
      item_venda iv
      inner join venda v
      on iv.venda = v.vend_codigo
    group by
      iv.produto, v.cliente

depois descobriria qual o cliente é o maior vendedor/comprador no geral

    SELECT
      v1.cliente,
      sum( iv1.qtd )  max_qtd       
    FROM
      item_venda iv1 
      inner join venda v1 on iv1.venda = v1.vend_codigo 
    GROUP BY v1.cliente

por fim, uniria estas duas subqueries para ter os totais por produto e no geral (que permitirá a ordenação) e a tabela de cliente (para pegar o nome)

SELECT GERAL.MAX_QTD, C.cli_nome, POR_PRODUTO.QTD, POR_PRODUTO.VALOR_TOTAL
FROM
  (
    SELECT 
      v.cliente, 
      iv.produto, 
      sum(iv.qtd) qtd, 
      sum(iv.valor) valor_total
    FROM
      item_venda iv
      inner join venda v
      on iv.venda = v.vend_codigo
    group by
      iv.produto, v.cliente
  ) POR_PRODUTO
  
  INNER JOIN 

  (
    SELECT 
      v1.cliente,
      SUM( iv1.qtd )  max_qtd
       
    FROM 
      item_venda iv1 
      inner join venda v1 on iv1.venda = v1.vend_codigo 
    GROUP BY v1.cliente
  ) GERAL
  ON POR_PRODUTO.cliente = GERAL.cliente

  INNER JOIN cliente C
  ON GERAL.cliente = C.cli_codigo

ORDER BY 
  GERAL.MAX_QTD DESC, C.cli_nome, POR_PRODUTO.QTD DESC

acho que isso resolve…

PERFEITO :shock:

Funcionou como uma luva aqui. Valeu :smiley: