Rollup PostgreSQL,但没有聚合?

wnrlj8wa  于 2023-04-11  发布在  PostgreSQL
关注(0)|答案(2)|浏览(164)

SQL的输出包含几列,其中六列是值,并且没有聚合类型。
我需要呈现这六列值的总和 在结果的最后一行。
我尝试使用ROLLUP和CUBE,但没有成功。
示例:

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

具有空值的行是仅呈现和的行。
我能够使用联合来重现我正在寻找的结果,但我相信这可能不是完成这一壮举的最佳方式。
真实的的选择:

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
vyswwuz2

vyswwuz21#

您可以使用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
cfh9epnr

cfh9epnr2#

建议您使用Bergi建议的CTE,并举例说明:

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

这将只运行一次原始查询,并使用其结果来计算UNION中的总和。现在我的机器上没有运行PostgreSQL,所以不能保证它会运行。

相关问题