sql - 在嵌套子查询中访问聚合

标签 sql postgresql subquery aggregate-functions window-functions

我有一个包含 order_idextended_price 列的 order_lines 表。我想知道扩展价格总和高于所有订单扩展价格总和平均值的订单。这是我得到的查询:

SELECT order_id, SUM(extended_price) AS "sumtotal"
FROM order_lines e
GROUP BY order_id
HAVING SUM(extended_price) > 
  (SELECT AVG(c.sumtotal) AS "avgtotal"
  FROM
    (SELECT order_id, SUM(extended_price) AS "sumtotal"
    FROM order_lines
    GROUP BY order_id) c
  )
ORDER BY sumtotal       

正如我们所见,我有一个子查询 c 来获取 sumtotal,它用于计算 avgtotal。但我正在运行与主查询相同的查询,以再次计算 sumtotal 并与 avgtotal 进行比较。有没有更好的方法来仅使用标准 SQL 功能来做到这一点。我正在使用 PostgreSQL。

最佳答案

一种方法是在子查询中的聚合函数上运行窗口函数:

SELECT order_id, sumtotal
FROM  (
   SELECT order_id
        , SUM(extended_price) AS sumtotal
        , AVG(SUM(extended_price)) OVER () AS avgtotal
   FROM   order_lines
   GROUP  BY order_id
   ) sub
WHERE  sumtotal > avgtotal;

应该会更快。

或者使用 CTE 来避免重复评估。不过,它会为实现临时结果增加一些成本。

WITH cte AS (
   SELECT order_id, SUM(extended_price) AS sumtotal
   FROM   order_lines
   GROUP  BY order_id
   )
SELECT order_id, sumtotal
FROM   cte
WHERE  sumtotal > (SELECT avg(sumtotal) FROM cte);

为了清晰起见,您可能会使用另一个 CTE 来计算平均值,但子查询通常成本更低。

相关:

关于sql - 在嵌套子查询中访问聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45039123/

相关文章:

MYSQL 包括列 w。计数为 0

mysql - 从具有 2 个条件的表中删除不需要的行

使用 EXISTS 和 OR 运算符的 SQL 查询

mysql - 用户在哪里 - 在 15 秒内增加选择?

查询中的 Php postgresql 变量

mysql - 如何从表中的字段获取值

sql - 如何过滤有序表,直到达到阈值的第一行?

php - 加入 MySql 表和 SUM

mysql - 如何使用 SQL 函数跨两个表进行更新

node.js - Nodejs应用程序的node-postgres vs pg-promise