Sql 在同一查询中使用SUM的结果

Sql 在同一查询中使用SUM的结果,sql,postgresql,aggregate-functions,postgresql-performance,Sql,Postgresql,Aggregate Functions,Postgresql Performance,由于交易总额和损失总额不在交易表中,因此上述内容不起作用。有没有办法让这个查询工作 注意:此查询涉及5亿行,因此需要提高效率 问题: 一些答案表明,SUM(transaction.transaction\u value)-SUM(transaction.loss\u value)是缓存的,不需要再次计算,因为其他人建议我应该作为派生表/子查询来避免重复计算。有人能指出一些可以解决意见分歧的东西吗 我正在使用postgres 9.3 答复: 我想在这里引用欧文的评论: 我对40k行进行了一次快速测

由于
交易总额
损失总额
不在
交易
表中,因此上述内容不起作用。有没有办法让这个查询工作

注意:此查询涉及5亿行,因此需要提高效率

问题:
一些答案表明,
SUM(transaction.transaction\u value)-SUM(transaction.loss\u value)
是缓存的,不需要再次计算,因为其他人建议我应该作为派生表/子查询来避免重复计算。有人能指出一些可以解决意见分歧的东西吗

我正在使用postgres 9.3

答复:

我想在这里引用欧文的评论:

我对40k行进行了一次快速测试,获胜者是没有子查询的普通版本。CTE是最慢的。因此,我认为我的第一个假设是错误的,查询计划者知道不必重复计算总和(也有道理)。在过去,我在更复杂的表达式中看到了不同的结果。随着每一个新版本的推出,计划员确实变得更加智能了

使用:

SELECT 
business_period,
SUM(transaction.transaction_value) AS total_transaction_value,
SUM(transaction.loss_value) AS total_loss_value,
(total_transaction_value - total_loss_value) AS net_value
FROM transaction
GROUP BY business_period

再次使用
sum

SELECT 
business_period,
SUM(transaction.transaction_value) AS total_transaction_value,
SUM(transaction.loss_value) AS total_loss_value,
(SUM(transaction.transaction_value) - SUM(transaction.loss_value)) AS net_value
FROM transaction
GROUP BY business_period

只需明确重申金额(我相信它们只计算一次):

或者,您可以使用派生表子查询,如果上面没有隐式地进行计算,则该子查询应该强制它只计算一次-尽管可能会有一些额外的开销,具体取决于优化器看到的内容:

SELECT 
  business_period,
  SUM(transaction.transaction_value) AS total_transaction_value,
  SUM(transaction.loss_value) AS total_loss_value,
  SUM(transaction.transaction_value) - SUM(transaction.loss_value) AS net_value
FROM transaction
GROUP BY business_period

使用子查询以避免重复计算:

SELECT business_period,
  total_transaction_value,
  total_loss_value,
  (total_transaction_value - total_loss_value) AS net_value
FROM
(
    SELECT 
       business_period,
       SUM(transaction.transaction_value) AS total_transaction_value,
       SUM(transaction.loss_value) AS total_loss_value,
    FROM transaction
    GROUP BY business_period
) x

或者是一种强制的方法,因为CTE是优化的障碍。对于这样的简单情况,子查询通常更快。Postgres更清楚,折叠子查询的速度更快。

我取的是缓存的总和(transaction.transaction\u值),不需要再次计算?@alumns是的,总和只计算一次。我取的是该总和(transaction.transaction\u值)是否已缓存且无需再次计算?是的,您已缓存,但db未将
总交易\u值
标识为列名。。因此,您需要再次使用该函数。请注意:不要在tabledefinitions中使用保留字/关键字。在大多数情况下,它会起作用,但你可能会有一些奇怪的行为。postgresql的关键字列表:Hey@DKSan,谢谢你的提示。这实际上不是我的模式,而是我为这个问题写的一个小东西。但下一次,我会确保让这个例子变得更好。谢谢你SUM(transaction.transaction_value)-其他人建议的SUM(transaction.loss_value)会导致重复计算吗?@校友:是的-尽管Postgres可以自由优化。SQL是一种声明性语言。实际上,只有一个CTE强制执行一次计算,但代价是更多的开销。子查询可能更便宜。不要只相信我的话,测试一下哪个更快。你不会发现有什么不同…@校友们:我对40k行进行了一次快速测试,获胜者是没有子查询的普通版本。CTE是最慢的。因此,我认为我的第一个假设是错误的,查询计划者知道不必重复计算总和(也有道理)。在过去,我在更复杂的表达式中看到了不同的结果。每一个新版本都会让计划者变得更聪明……再次感谢您始终深入的回答!:)
SELECT business_period,
  total_transaction_value,
  total_loss_value,
  (total_transaction_value - total_loss_value) AS net_value
FROM
(
    SELECT 
       business_period,
       SUM(transaction.transaction_value) AS total_transaction_value,
       SUM(transaction.loss_value) AS total_loss_value,
    FROM transaction
    GROUP BY business_period
) x
SELECT *, total_transaction_value - total_loss_value AS net_value
FROM  (
   SELECT business_period
        , SUM(transaction_value) AS total_transaction_value
        , SUM(loss_value)        AS total_loss_value
   FROM   transaction
   GROUP  BY 1
   ) sub;