You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL新手求助:解决聚合函数报错及获取单一最高采购成本结果问题

问题分析与解决方案

嘿,我来帮你搞定这两个SQL问题,咱们一步步拆解:

1. 修复“未将表达式包含在聚合函数中”的报错

这个报错的核心原因是:当你在查询中使用MAX()这类聚合函数时,SQL要求SELECT列表里的每一列要么是聚合函数(比如MAX、SUM),要么必须被包含在GROUP BY子句中。你的原查询里,SalesPersonIDFirstNameLastName这些列既没有用聚合函数处理,也没放在GROUP BY里,数据库无法确定这些列和MAX(ProcurementCost)的对应关系,所以会抛出错误。

不过这里要注意:如果你的需求是找到对应最高ProcurementCost的那条具体记录,直接加GROUP BY并不是最优解——因为GROUP BY会把同一个SalesPersonID的所有行合并成一行,而你需要的是那条拥有最高成本的原始行。

2. 获取单一结果的正确写法

根据你的需求(基于特定条件获取最高ProcurementCost的单一结果),这里提供两种常用的可行方案:

方案1:子查询匹配最高值

先通过子查询找到SalesPersonID=5的所有记录中的最高ProcurementCost,再筛选出对应这条最高值的完整记录:

SELECT sp.SalesPersonID, sp.FirstName, sp.LastName, sp.Region, 
       prc.SalesRevenueYear1, prc.SalesRevenueYear2, prc.ProcurementCost
FROM SalesPeople sp
INNER JOIN ProductRevenueAndCosts prc 
    ON sp.SalesPersonID = prc.SalesPersonID
WHERE prc.SalesPersonID = 5
  AND prc.ProcurementCost = (
      SELECT MAX(ProcurementCost) 
      FROM ProductRevenueAndCosts 
      WHERE SalesPersonID = 5
  );

注:如果存在多条记录共享同一个最高ProcurementCost,这个查询会返回所有这些行。如果需要强制只返回一条,可以在末尾加LIMIT 1(MySQL/PostgreSQL)或者TOP 1(SQL Server)。

方案2:使用窗口函数(推荐,适用于支持窗口函数的数据库)

窗口函数可以给每条记录按ProcurementCost降序排名,然后直接取排名第一的那条:

SELECT SalesPersonID, FirstName, LastName, Region, 
       SalesRevenueYear1, SalesRevenueYear2, ProcurementCost
FROM (
    SELECT sp.SalesPersonID, sp.FirstName, sp.LastName, sp.Region, 
           prc.SalesRevenueYear1, prc.SalesRevenueYear2, prc.ProcurementCost,
           -- 按ProcurementCost降序排名,最高的排第1
           ROW_NUMBER() OVER (ORDER BY prc.ProcurementCost DESC) AS row_rank
    FROM SalesPeople sp
    INNER JOIN ProductRevenueAndCosts prc 
        ON sp.SalesPersonID = prc.SalesPersonID
    WHERE prc.SalesPersonID = 5
) ranked_records
WHERE row_rank = 1;
  • 如果有多个行并列最高,ROW_NUMBER()会随机给它们分配不同的排名,只返回其中一条;如果想保留所有并列第一的行,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK()

补充:如果确实需要聚合结果

如果你的作业需求是获取该销售的基本信息,加上他的最高ProcurementCost(而非具体某条记录),那可以用GROUP BY来修复报错,注意把所有非聚合列都放到GROUP BY里,同时对年份收入列使用合适的聚合函数(比如MAX、SUM,根据需求选择):

SELECT sp.SalesPersonID, sp.FirstName, sp.LastName, sp.Region, 
       MAX(prc.SalesRevenueYear1) AS SalesRevenueYear1,
       MAX(prc.SalesRevenueYear2) AS SalesRevenueYear2,
       MAX(prc.ProcurementCost) AS MaxProcurementCost
FROM SalesPeople sp
INNER JOIN ProductRevenueAndCosts prc 
    ON sp.SalesPersonID = prc.SalesPersonID
WHERE prc.SalesPersonID = 5
GROUP BY sp.SalesPersonID, sp.FirstName, sp.LastName, sp.Region;

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

火山引擎 最新活动