在 ANSI SQL 里,“分组”主要用 GROUP BY 子句来实现,用来把多行数据按某些列“分堆”,再对每一堆做聚合计算。
下面按从基础到进阶给你讲清楚。
orders
+----------+------------+--------+
| order_id | customer_id| amount |
+----------+------------+--------+
| 1 | 101 | 200 |
| 2 | 101 | 300 |
| 3 | 102 | 150 |
+----------+------------+--------+
SELECT
customer_id,
COUNT(*) AS order_count
FROM orders
GROUP BY customer_id;
✅ 结果:
customer_id | order_count
------------+------------
101 | 2
102 | 1
| 函数 | 含义 |
|---|---|
| COUNT(*) | 行数 |
| SUM(col) | 求和 |
| AVG(col) | 平均值 |
| MAX(col) | 最大值 |
| MIN(col) | 最小值 |
SELECT
customer_id,
SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id;
WHERE 过滤“分组前”
HAVING 过滤“分组后”
SELECT
customer_id,
SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 400;
SELECT
customer_id,
YEAR(order_date) AS order_year,
COUNT(*) AS cnt
FROM orders
GROUP BY customer_id, YEAR(order_date);
⚠️ 注意:
SELECT 里出现的非聚合列,必须出现在 GROUP BY 中(ANSI SQL 严格要求)。
SELECT
customer_id,
SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
ORDER BY total_amount DESC;
FROM
→ WHERE
→ GROUP BY
→ HAVING
→ SELECT
→ ORDER BY
SELECT
customer_id,
order_id, -- ❌ 不在 GROUP BY 中
SUM(amount)
FROM orders
GROUP BY customer_id;
✅ 正确做法:
order_id 加入 GROUP BYorder_id 使用聚合函数SELECT
customer_id,
YEAR(order_date),
SUM(amount)
FROM orders
GROUP BY ROLLUP(customer_id, YEAR(order_date));
SELECT
customer_id,
YEAR(order_date),
SUM(amount)
FROM orders
GROUP BY GROUPING SETS (
(customer_id, YEAR(order_date)),
(customer_id),
()
);
ANSI SQL 分组 = GROUP BY + 聚合函数 + HAVING
如果你愿意,可以告诉我:
我可以给你更贴近实际场景的写法。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。