Rollup PostgreSQL,但不进行聚合?

huangapple go评论66阅读模式
英文:

Rollup PostgreSQL, but without aggregate?

问题

I'm here to help with the translation. Please specify which parts you'd like to be translated.

英文:

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

答案1

得分: 1

你可以使用 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
英文:

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

答案2

得分: 0

使用像Bergi建议的CTE,并附带示例:

使用CTE基础表格 AS (
   原始查询
)

选择 
    col1,col2,col3,col4,col5,col6,col7,col8,col9
从 CTE基础表格
联接全部
选择 null, null, null, null, null, null, sum(col7), sum(col8), sum(col9)
从 CTE基础表格

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

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.

huangapple
  • 本文由 发表于 2023年4月11日 06:38:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75981244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定