You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle 11g SQL数学计算问题:查询符合条件的图书类别及平均折扣后零售价

解决你的SQL查询问题

首先咱们拆解下你的需求:要找出所有图书类别,这些类别的平均折扣后零售价,需要低于所有类别图书的最高平均零售价(这里的“平均零售价”指每个类别自身的零售均价中的最大值),最后显示符合条件的类别及对应的平均折扣后零售价。

先说说你原来查询里的几个核心问题:

  • SQL里不能在SELECT的聚合函数中引用同一句子的别名(比如avg(A)里的A),因为聚合计算的顺序在别名生成之前,引擎识别不了这个别名
  • WHERE子句是用来过滤单条行数据的,不能直接用聚合函数的结果(比如B<max(C)),聚合结果的过滤得用HAVING或者子查询/CTE来实现
  • 你的数据里部分discount是空值(比如FITNESS类别的图书),直接计算retail-discount会得到NULL,导致平均值计算不准确,得用COALESCE(discount, 0)把空折扣当成0来处理

正确的查询写法

这里用CTE(公共表表达式)分步计算,逻辑更清晰易懂:

WITH category_stats AS (
    -- 第一步:计算每个类别的平均折扣后零售价和平均零售价
    SELECT 
        category,
        AVG(retail - COALESCE(discount, 0)) AS avg_discounted_retail,
        AVG(retail) AS avg_retail
    FROM books
    GROUP BY category
),
max_global_avg_retail AS (
    -- 第二步:找到所有类别中最高的平均零售价
    SELECT MAX(avg_retail) AS highest_avg_retail
    FROM category_stats
)
-- 第三步:筛选出平均折扣后价低于最高平均零售价的类别
SELECT cs.category, cs.avg_discounted_retail
FROM category_stats cs
CROSS JOIN max_global_avg_retail mar
WHERE cs.avg_discounted_retail < mar.highest_avg_retail
ORDER BY cs.category;

如果不习惯用CTE,也可以用嵌套子查询的写法:

SELECT 
    category,
    AVG(retail - COALESCE(discount, 0)) AS avg_discounted_retail
FROM books
GROUP BY category
HAVING AVG(retail - COALESCE(discount, 0)) < (
    -- 子查询获取所有类别平均零售价的最大值
    SELECT MAX(avg_retail)
    FROM (
        SELECT AVG(retail) AS avg_retail
        FROM books
        GROUP BY category
    ) AS category_avg_retails
);

结果说明

根据你提供的数据,所有类别的平均折扣后零售价都低于全局最高的平均零售价(FAMILY LIFE类别的零售均价55.975),所以最终会返回所有类别及其对应的平均折扣后零售价。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:40:51