解决方法:
- [ ]使用聚合函数(如SUM(), AVG(), MAX(), MIN(), COUNT()等)来对分组后的每个组进行某种形式的汇总,同时使用GROUP BY语句来指定分组的依据。如果你想显示非聚合的列,可以使用GROUP BY语句但不使用聚合函数。
例如,假设你有一个销售数据表sales,包含salesperson_id, amount, region等列,你想按region分组并显示每个区域的销售总额和每个区域的第一条记录的销售人员ID:
SELECT region,
SUM(amount) AS total_sales,
MIN(salesperson_id) AS salesperson_id
FROM sales
GROUP BY region;
- 子查询加join 这种一般在连表的情况下用的较多,步骤是:先通过子查询先获取每个分组的特定行(例如,每个分组的最大值或最小值对应的行),然后通过JOIN将这些行与原始表连接以获取更多信息。
例如,获取每个区域销售额最高的销售人员信息:
SELECT s.*
FROM sales s
JOIN (
SELECT region, MAX(amount) AS max_amount
FROM sales
GROUP BY region
) r ON s.region = r.region AND s.amount = r.max_amount;
这是单表, join的 另一张查出来的表中运用了第一中聚合函数的方法。
连表情形:假设你有一个名为Orders的表,其中包含OrderID、CustomerID、OrderDate和TotalAmount等列,你想按CustomerID分组,并显示每个客户的最早订单日期以及总订单金额。同时,还想显示其他与客户相关的信息(例如CustomerName),您可以使用子查询:
SELECT
o.CustomerID,
c.CustomerName,
MIN(o.OrderDate) AS EarliestOrderDate,
SUM(o.TotalAmount) AS TotalOrderAmount
FROM
Orders o
INNER JOIN
Customers c ON o.CustomerID = c.CustomerID
GROUP BY
o.CustomerID, c.CustomerName;
group by 后面指定了两个属性 会先按第一个分组,统计月度商品销量或者啥仓库库存数量时经常用。
- 使用窗口函数: 如果你想要在分组的同时显示每个分组内的特定行的其他列(例如,每个分组的最大值对应的行),可以使用窗口函数(如ROW_NUMBER(), RANK(), DENSE_RANK(), LEAD(), LAG()等)。
例如,如果你想按region分组,并显示每个区域销售额最高的销售人员的详细信息(包括他们的ID、姓名等):
WITH RankedSales AS (
SELECT salesperson_id,
amount,
region,
RANK() OVER (PARTITION BY region ORDER BY amount DESC
) as rank
FROM sales
)
SELECT salesperson_id,
amount,
region
FROM RankedSales
WHERE rank = 1;
over 前面的函数一定要有 不需要RANK 的可以 使用ROW_NUMBER 等其他一些函数,在这个例子中,我们首先使用WITH子句创建一个临时结果集RankedSales,其中包含每个销售记录的排名(按region分区,按amount降序排序)。然后,我们从该临时结果集中选择排名为1的记录,即每个区域销售额最高的记录。