Rollup PostgreSQL,但不进行聚合?

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

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:

  1. col1|col2|col3|col4|col5|col6|col7|col8|col9
  2. xxxx|xxxx|xxxx|xxxx|xxxx|xxxx| 1| 5| 9
  3. yyyy|yyyy|yyyy|yyyy|yyyy|yyyy| 10| 8| 0
  4. zzzz|zzzz|zzzz|zzzz|zzzz|zzzz| 3| 50| 1
  5. 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:

  1. select
  2. p.numero pedido,
  3. v.nome nome_vendedor,
  4. cpr.numero ordem_venda,
  5. case ppi.tipo_produto_item
  6. when 'TPI10' then '10'
  7. when 'TPI20' then '20'
  8. when 'TPI30' then '30'
  9. else '??'
  10. end item,
  11. ppi.descricao,
  12. p2.nome nome_cliente,
  13. upper(c.nome) cidade,
  14. e.uf,
  15. round(pov.valor * ppi.percentual / 100, 2) valor_ordem_venda, -- sum this
  16. pov.percentual_comissao,
  17. round(pov.valor * ppi.percentual * pov.percentual_comissao / 10000, 2) comissao, -- sum this
  18. round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_total, 2) valor_venda, -- sum this
  19. round(((pov.valor * ppi.percentual / 100) / p.valor_total_nota) * p.valor_nota_redemil, 2) valor_nota, -- sum this
  20. case row_number() over(partition by p.numero order by p.numero)
  21. when 1 then coalesce(pdrd.despesa, 0.00)
  22. else 0.00
  23. end despesa_pedido, -- sum this
  24. case row_number() over(partition by p.numero order by p.numero)
  25. when 1 then coalesce(pdrc.receita, 0.00)
  26. else 0.00
  27. end receita_pedido, -- sum this
  28. case
  29. 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)
  30. 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)
  31. 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)
  32. 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)
  33. else 0.00
  34. end "over", -- sum this
  35. case ppi.tipo_produto_item
  36. when 'TPI10' then ov.numero_nota_10
  37. when 'TPI20' then ov.numero_nota_20
  38. when 'TPI30' then ov.numero_nota_30
  39. else null
  40. end nota,
  41. cpr.data_faturamento
  42. from
  43. financeiro.contas_pagar_receber cpr
  44. inner join financeiro.contas_pagar_receber_itens cpri on cpri.id_conta_pagar_receber = cpr.id_conta_pagar_receber
  45. inner join pedido.pedidos p on p.id_pedido = cpr.id_pedido
  46. inner join pedido.pedidos_vendedores pv on pv.id_pedido = p.id_pedido
  47. inner join cadastro.vendedores v on v.id_vendedor = pv.id_vendedor
  48. inner join pedido.pedidos_produtos pp on pp.id_pedido = p.id_pedido
  49. 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
  50. inner join cadastro.pessoas p2 on p2.id_pessoa = p.id_cliente
  51. inner join cadastro.pessoas_enderecos pe on pe.id_pessoa = p.id_cliente
  52. inner join cadastro.cidades c on c.id_cidade = pe.id_cidade
  53. inner join cadastro.estados e on e.id_estado = c.id_estado
  54. inner join pedido.pedidos_ordens_vendas pov on pov.numero_ordem_venda = cpr.numero
  55. inner join cadastro.ordens_vendas ov on ov.numero_ordem_venda = cpr.numero
  56. left join
  57. (
  58. select
  59. pdr.id_pedido,
  60. sum
  61. (
  62. case pdr.tipo_lancamento
  63. when 'D' then pdr.valor
  64. else 0.00
  65. end
  66. ) despesa
  67. from
  68. pedido.pedidos_despesas_receitas pdr
  69. group by
  70. pdr.id_pedido
  71. ) pdrd on pdrd.id_pedido = p.id_pedido
  72. left join
  73. (
  74. select
  75. pdr.id_pedido,
  76. sum
  77. (
  78. case pdr.tipo_lancamento
  79. when 'C' then pdr.valor
  80. else 0.00
  81. end
  82. ) receita
  83. from
  84. pedido.pedidos_despesas_receitas pdr
  85. group by
  86. pdr.id_pedido
  87. ) pdrc on pdrc.id_pedido = p.id_pedido
  88. where
  89. cpr.data_faturamento notnull and
  90. cpr.data_faturamento between :pidt_faturamentoinicio and :pidt_faturamentofinal and
  91. cpr.id_pedido_vendedor is null and
  92. cpri.tipo_produto_item in ('TPI10', 'TPI20', 'TPI30') and
  93. p.tipo_pedido in ('D', 'R') and
  94. pp.tipo_produto_pedido = 'V'
  95. order by
  96. p.numero,
  97. cpr.numero,
  98. ppi.tipo_produto_item

答案1

得分: 1

你可以使用 UNION ALL 来添加另一行:

  1. SELECT
  2. col1, col2, col3, col4, col5, col6, col7, col8, col9
  3. FROM Table1
  4. UNION ALL
  5. SELECT
  6. null, null, null, null, null, null, SUM(col7), SUM(col8), SUM(col9)
  7. FROM Table1
英文:

You can add anothe rrow with UNION ALL

  1. SELECT
  2. col1,col2,col3,col4,col5,col6,col7,col8,col9
  3. FROM Table1
  4. UNION ALL
  5. SELECT
  6. null,null,null,null,null,null,SUM(col7),SUM(col8),SUM(col9)
  7. FROM Table1

答案2

得分: 0

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

  1. 使用CTE基础表格 AS (
  2. 原始查询
  3. )
  4. 选择
  5. col1,col2,col3,col4,col5,col6,col7,col8,col9
  6. CTE基础表格
  7. 联接全部
  8. 选择 null, null, null, null, null, null, sum(col7), sum(col8), sum(col9)
  9. CTE基础表格
  10. 这将仅运行一次原始查询,并使用其结果计算UNION中的总和。我现在的机器上没有运行PostgreSQL,所以不能保证它会直接运行。
英文:

Suggesting you use a CTE as Bergi suggested, with an example:

  1. WITH cte_base AS (
  2. ORIGINAL QUERY
  3. )
  4. SELECT
  5. col1,col2,col3,col4,col5,col6,col7,col8,col9
  6. FROM cte_base
  7. UNION ALL
  8. SELECT null, null, null, null, null, null, sum(col7), sum(col8), sum(col9)
  9. 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:

确定