问题解决
假设我们现在有一张用户钱包表 该表包含着四个字段 气质ID字段是递增的 还有用户名(username), 货币数量(currency), 添加时间(addTime), 用户的货币数量随着时间的变化而更新
现在我们需要查询每个用户的最新货币数量,首先我们需要对列表进行排序并对用户去重,所以我们就简单的写了一条sql语句并执行:
1 | select distinct username, currency, addTime from user_wallet order by addTime desc; |
结果显示:
结果显示去重并未生效,在网上查看的资料后,其原因是distinct
只能返回他的目标字段,而无法返回其他字段,所以我们使用group by
进行去重 在使用group by
之前,由于我本地的MySQL 版本是5.7,而MySQL5.7 默认的 MySQL 配置中 sql_mode
配置了 only_full_group
,需要 GROUP BY
中包含所有 在 SELECT 中出现的字段, 所以我们需要在MySQL 的配置中去掉这个配置:
在 配置文件(my.cnf)中 修改 sql_mode 的配置为:
1 | $ vim /usr/local/etc/my.cnf |
然后重启MYSQL服务即可:
结果显示,去重已经生效,但是排序未生效,这是因为我们是先去重拿到结果后再进行的排序,所以排序也是针对于去重后的结果进行排序,所以我们对这条Sql语句进行修改:
1 | select username, currency, addTime FROM (select username, currency, addTime from user_wallet order by addTime DESC) alias GROUP BY username; |
结果发现排序还是未能生效,
小编在查阅了相关资料后,发现在mysql 5.7 中 ,这种语法并没有效果,正确的写法是:
1 | select username, currency, addTime FROM (select username, currency, addTime from user_wallet order by addTime DESC limit 0, 10000) alias GROUP BY username; |
通过 explain 查看执行计划,可以看到没有 limit 的时候,少了一个 DERIVED 操作。DERIVED用于派生表的SELECT(FROM子句的子查询),所以没有它就相当于子句里的排序并没有被执行。至此问题解决
注意事项
- 采用子句查询时,别名(alias)不可少,会报语法错误
- 如果有分页,分页条件要写在子句里面
- 需要去重mysql的严格模式