来自http://tunps.com/mysql-group-by-exp
ECShop里面有两个表,一个是ecs_order_action ,以下是它的表结构
| Field | Type | Null | Key | Default | Extra |
| action_id | mediumint(8) unsigned | NO | PRI | (NULL) | auto_increment |
| order_id | mediumint(8) unsigned | NO | MUL | 0 | |
| action_user | varchar(30) | NO | |||
| order_status | tinyint(1) unsigned | NO | 0 | ||
| shipping_status | tinyint(1) unsigned | NO | 0 | ||
| pay_status | tinyint(1) unsigned | NO | 0 | ||
| action_place | tinyint(1) unsigned | NO | 0 | ||
| action_note | varchar(255) | NO | |||
| log_time | int(11) unsigned | NO | 0 |
这个表的功能是订单的管理日志,order_id是订单号,action_user是操作订单的管理员名称,取自ecs_admin_user.user_name,order_status是订单状态,当order_status=1的时候,订单为确认状态,0表示未确认,log_time是操作unix时间戳。
还有一个表是ecs_admin_user,表结构如下:
| Field | Type | Null | Key | Default | Extra |
| user_id | smallint(5) unsigned | NO | PRI | (NULL) | auto_increment |
| user_name | varchar(60) | NO | MUL | ||
| varchar(60) | NO | ||||
| password | varchar(32) | NO | |||
| add_time | int(11) | NO | 0 | ||
| last_login | int(11) | NO | 0 | ||
| last_ip | varchar(15) | NO | |||
| action_list | text | NO | (NULL) | ||
| nav_list | text | NO | (NULL) | ||
| lang_type | varchar(50) | NO | |||
| agency_id | smallint(5) unsigned | NO | MUL | (NULL) | |
| suppliers_id | smallint(5) unsigned | YES | 0 | ||
| todolist | longtext | YES | (NULL) | ||
| role_id | smallint(5) | YES | (NULL) |
user_id是用户id,user_name和order_action.action_user相对应(但并没有关联)。当order_status=1,且log_time为最早时间为点击“确认”那个管理员(虽然事实上ECShop里面无法正确的通过这种方式取得点击“确定”的管理员,因为管理员A可以先点击“付费”或者“售后”都将自定把订单转为“已确认”状态,然后管理员B点击“确定”,那么这个方法就会认为管理员A才是点“确认”的人,因为他是最先将order_status修改为1的人)。
现在我们的需求是:找到每个订单点击确认的用户id,结果类似于:
| order_id | user_id |
| 123 | 1 |
| 124 | 2 |
刚开始写的SQL:
SELECT * FROM
(
SELECT order_id,user_id FROM ecs_order_action oa INNER JOIN ecs_admin_user au ON oa.action_user=au.user_name
AND oa.order_status=1
) AS tb1
GROUP BY order_id
但是发现结果有问题,然后修改为:
SELECT * FROM
(
SELECT order_id,user_id FROM ecs_order_action oa INNER JOIN ecs_admin_user au ON oa.action_user=au.user_name
AND oa.order_status=1 ORDER BY log_time
) AS tb1
GROUP BY order_id
结果都是返回的128rows,将两次结果通过SQLyog输出为xml,然后用Notepad++的Compare功能比较:
发现确实有很多行的数据是不同的,通过这个实验,可以发现group by的每次取的结果都是第一次出现新order_id那行,为了按log_time顺序排列,必须order by log_time,将时间最早的结果输出。
