mysql group by 和order by 执行顺序

本文探讨了MySQL中GROUP BY和ORDER BY的执行顺序问题,并提供了两种不同的查询方式来改变这一顺序。一种是先按用户ID分组再按历史记录ID排序,另一种则是先按历史记录ID排序后再进行分组。
Mysql 中group by 和 order by的顺序问题:


1: select historyId ,userId, date from history group by userId order by historyId desc;
以上1代码查询的结果是这样的:
+-----------+--------+---------------------+
| historyId | userId | date |
+-----------+--------+---------------------+
| 317 | 139 | 2010-08-28 18:12:11 |
| 310 | 138 | 2010-08-28 17:35:52 |
| 306 | 137 | 2010-08-28 17:30:20 |
| 303 | 135 | 2010-08-28 17:25:20 |
| 292 | 131 | 2010-08-27 17:43:43 |
| 274 | 38 | 2010-08-26 11:42:28 |
| 258 | 100 | 2010-08-25 15:01:46 |
| 249 | 2 | 2010-08-20 18:37:02 |
| 233 | 10 | 2010-08-23 17:58:42 |
| 162 | 31 | 2010-08-19 16:56:09 |
| 151 | 39 | 2010-08-19 15:48:33 |
| 124 | 1 | 2010-08-19 10:01:24 |
+-----------+--------+---------------------+
说明是先group by user_id 然后再 order by historyId 的。那么怎样让程序先执行order by historyId ?

这样可以行的通:

2;select historyId ,userId,date from (select * from history order by historyId desc) c group by userId order by historyId desc;
以上代码2查询的结果是这样的:
+-----------+--------+---------------------+
| historyId | userId | date |
+-----------+--------+---------------------+
| 394 | 1 | 2010-09-03 14:45:30 |
| 386 | 100 | 2010-09-03 11:39:08 |
| 381 | 2 | 2010-09-02 19:43:33 |
| 335 | 39 | 2010-08-31 15:28:27 |
| 318 | 139 | 2010-08-28 18:12:53 |
| 316 | 138 | 2010-08-28 18:10:40 |
| 309 | 137 | 2010-08-28 17:31:02 |
| 305 | 135 | 2010-08-28 17:26:23 |
| 296 | 131 | 2010-08-27 17:55:41 |
| 284 | 38 | 2010-08-26 16:46:06 |
| 233 | 10 | 2010-08-23 17:58:42 |
| 218 | 31 | 2010-08-23 15:46:02 |
+-----------+--------+---------------------+
很明显:代码2执行的结果告诉我们查询的顺序是先通过order by 排序,在通过group by 排序 ,最后通过 order 对这个查询结果进行一个整体的排序。
MySQL 中,`GROUP BY` `ORDER BY` 是两个常用的 SQL 子句,它们在查询中承担不同的角色: --- ### ✅ 1. `GROUP BY` **作用:** 用于将结果集按一个或多个列进行分组。通常与聚合函数(如 `COUNT()`、`SUM()`、`AVG()`、`MAX()`、`MIN()`)一起使用,以对每个分组进行统计。 **语法示例:** ```sql SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name; ``` --- ### ✅ 2. `ORDER BY` **作用:** 用于对查询结果进行排序,默认是升序(`ASC`),也可以使用 `DESC` 指定降序排序。 **语法示例:** ```sql SELECT column_name FROM table_name ORDER BY column_name [ASC | DESC]; ``` --- ## ✅ 示例讲解 我们以一个 `orders` 表为例: | order_id | user_id | amount | order_date | |----------|---------|--------|-------------| | 1 | 101 | 200 | 2024-01-10 | | 2 | 102 | 150 | 2024-01-11 | | 3 | 101 | 300 | 2024-01-12 | | 4 | 103 | 100 | 2024-01-10 | | 5 | 102 | 250 | 2024-01-13 | --- ### ✅ 示例 1:使用 `GROUP BY` 统计每个用户的总消费金额 ```sql SELECT user_id, SUM(amount) AS total_amount FROM orders GROUP BY user_id; ``` **结果:** | user_id | total_amount | |---------|--------------| | 101 | 500 | | 102 | 400 | | 103 | 100 | --- ### ✅ 示例 2:使用 `ORDER BY` 对结果进行排序 ```sql SELECT user_id, SUM(amount) AS total_amount FROM orders GROUP BY user_id ORDER BY total_amount DESC; ``` **结果:** | user_id | total_amount | |---------|--------------| | 101 | 500 | | 102 | 400 | | 103 | 100 | --- ### ✅ 示例 3:结合 `GROUP BY` `ORDER BY` 查询最近订单时间 ```sql SELECT user_id, MAX(order_date) AS latest_order_date FROM orders GROUP BY user_id ORDER BY latest_order_date DESC; ``` **结果:** | user_id | latest_order_date | |---------|-------------------| | 102 | 2024-01-13 | | 101 | 2024-01-12 | | 103 | 2024-01-10 | --- ## ✅ 使用顺序:`GROUP BY` `ORDER BY` 的执行顺序 SQL 查询的执行顺序如下(部分): 1. `FROM` 2. `WHERE` 3. `GROUP BY` 4. `SELECT` 5. `ORDER BY` 因此,**先分组再排序**,即 `GROUP BY` 在 `ORDER BY` 之前执行。 --- ## ✅ 注意事项 - 在 `SELECT` 中出现的非聚合字段,**必须出现在 `GROUP BY` 子句中**。 - `ORDER BY` 可以使用别名排序(在 MySQL 中支持),例如 `ORDER BY total_amount DESC`。 - 如果查询中包含 `GROUP BY` `ORDER BY`,尽量确保排序字段在 `SELECT` 中已定义。 --- ## ✅ 总结对比 | 特性 | `GROUP BY` | `ORDER BY` | |------|------------|-------------| | 作用 | 分组聚合 | 排序 | | 可用函数 | 聚合函数(如 SUM, MAX) | 不影响计算 | | 执行顺序 | 先执行 | 后执行 | | 是否必须 | 否 | 否 | | 是否可使用别名 | 否(MySQL 中部分版本支持) | 是(MySQL 支持) | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值