skip to Main Content

A SQL has an output with several columns, six of which are values, and there is no type of aggregation.

I need to present the sum of these six columns of values ​​in the last line of the result.

I tried to use ROLLUP and CUBE but without success.

Example:

col1|col2|col3|col4|col5|col6|col7|col8|col9
xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|   1|   5|   9
yyyy|yyyy|yyyy|yyyy|yyyy|yyyy|  10|   8|   0
zzzz|zzzz|zzzz|zzzz|zzzz|zzzz|   3|  50|   1
null|null|null|null|null|null|  14|  63|  10

The row with nulls is the one that presents only the sums.

I was able to reproduce the result I’m looking for using a union, but I believe this may not be the best way to accomplish this feat.

The real select:

select
   p.numero pedido,
   v.nome nome_vendedor,
   cpr.numero ordem_venda,
   case ppi.tipo_produto_item
      when 'TPI10' then '10'
      when 'TPI20' then '20'
      when 'TPI30' then '30'
      else '??'
   end item,
   ppi.descricao,
   p2.nome nome_cliente,
   upper(c.nome) cidade,
   e.uf,
   round(pov.valor * ppi.percentual / 100, 2) valor_ordem_venda, -- sum this
   pov.percentual_comissao,
   round(pov.valor * ppi.percentual * pov.percentual_comissao / 10000, 2) comissao, -- sum this
   round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_total, 2) valor_venda, -- sum this
   round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_nota_redemil, 2) valor_nota, -- sum this
   case row_number() over(partition by p.numero order by p.numero)
      when 1 then coalesce(pdrd.despesa, 0.00)
      else 0.00
   end despesa_pedido, -- sum this
   case row_number() over(partition by p.numero order by p.numero)
      when 1 then coalesce(pdrc.receita, 0.00)
      else 0.00
   end receita_pedido, -- sum this
   case
      when p.tipo_pedido = 'D' and not p.recebe_usado then round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_total, 2) - round(pov.valor * ppi.percentual / 100, 2)
      when p.tipo_pedido = 'R' and not p.recebe_usado then round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_total, 2) - round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_nota_redemil, 2)
      when p.tipo_pedido = 'D' and p.recebe_usado then round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_total * p.percentual_lucro_pedido / 100, 2) - round(pov.valor * ppi.percentual * pov.percentual_comissao / 10000, 2)
      when p.tipo_pedido = 'R' and p.recebe_usado then round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_nota_redemil * (100 - p.percentual_pis_cofins - p.percentual_icms) / 100, 2) - round((pov.valor * ppi.percentual / 100) * (100 - pov.percentual_pis_cofins - pov.percentual_icms) / 100, 2)
      else 0.00
   end "over", -- sum this
   case ppi.tipo_produto_item
      when 'TPI10' then ov.numero_nota_10
      when 'TPI20' then ov.numero_nota_20
      when 'TPI30' then ov.numero_nota_30
      else null
   end nota,
   cpr.data_faturamento
from
   financeiro.contas_pagar_receber cpr
inner join financeiro.contas_pagar_receber_itens cpri on cpri.id_conta_pagar_receber = cpr.id_conta_pagar_receber
inner join pedido.pedidos p on p.id_pedido = cpr.id_pedido
inner join pedido.pedidos_vendedores pv on pv.id_pedido = p.id_pedido
inner join cadastro.vendedores v on v.id_vendedor = pv.id_vendedor
inner join pedido.pedidos_produtos pp on pp.id_pedido = p.id_pedido
inner join pedido.pedidos_produtos_itens ppi on ppi.id_pedido_produto = pp.id_pedido_produto and ppi.tipo_produto_item = cpri.tipo_produto_item
inner join cadastro.pessoas p2 on p2.id_pessoa = p.id_cliente
inner join cadastro.pessoas_enderecos pe on pe.id_pessoa = p.id_cliente
inner join cadastro.cidades c on c.id_cidade = pe.id_cidade
inner join cadastro.estados e on e.id_estado = c.id_estado
inner join pedido.pedidos_ordens_vendas pov on pov.numero_ordem_venda = cpr.numero
inner join cadastro.ordens_vendas ov on ov.numero_ordem_venda = cpr.numero
left join
   (
      select
         pdr.id_pedido,
         sum
         (
            case pdr.tipo_lancamento
               when 'D' then pdr.valor
               else 0.00
            end
         ) despesa
      from
         pedido.pedidos_despesas_receitas pdr
      group by
         pdr.id_pedido
   ) pdrd on pdrd.id_pedido = p.id_pedido
left join
   (
      select
         pdr.id_pedido,
         sum
         (
            case pdr.tipo_lancamento
               when 'C' then pdr.valor
               else 0.00
            end
         ) receita
      from
         pedido.pedidos_despesas_receitas pdr
      group by
         pdr.id_pedido
   ) pdrc on pdrc.id_pedido = p.id_pedido
where
   cpr.data_faturamento notnull and
   cpr.data_faturamento between :pidt_faturamentoinicio and :pidt_faturamentofinal and
   cpr.id_pedido_vendedor is null and
   cpri.tipo_produto_item in ('TPI10', 'TPI20', 'TPI30') and
   p.tipo_pedido in ('D', 'R') and
   pp.tipo_produto_pedido = 'V'
order by
   p.numero,
   cpr.numero,
   ppi.tipo_produto_item

2

Answers


  1. You can add anothe rrow with UNION ALL

    SELECT
        col1,col2,col3,col4,col5,col6,col7,col8,col9
    FROM Table1
    UNION ALL
    SELECT 
        null,null,null,null,null,null,SUM(col7),SUM(col8),SUM(col9)
    FROM Table1
    
    Login or Signup to reply.
  2. Suggesting you use a CTE as Bergi suggested, with an example:

        WITH cte_base AS (
           ORIGINAL QUERY
        )
        
        SELECT 
            col1,col2,col3,col4,col5,col6,col7,col8,col9
        FROM cte_base
        UNION ALL
        SELECT null, null, null, null, null, null, sum(col7), sum(col8), sum(col9)
        FROM cte_base
    

    This will run the original query only once, and use its results to calculate the sums in the UNION. Don’t have PostgreSQL running on my machine right now so no guarantees it will run out of the box.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search