MySQL 实现不同分组取不同值
简述
最近做项目过程中遇到这样一个需求:实现不同分组取不同的值(类似先排序再分组),具体需求如下:
(1)将客户按手机号进行分组;
(2)分组之后数据如果有部门A,则优先取部门A数据;
(3)如果分组数据中没有部门A的数据,则优先取先录入的数据。
先来看表结构:
解决思路
(1)实现分组,并获取分组数据中最先导入的【cphone分组+addtime时间正序】
SELECT
cid,
cphone,
addtime
FROM
(
SELECT
cid,
cphone,
addtime
FROM
crm_test
ORDER BY
addtime
) AS a
GROUP BY
cphone
LIMIT 0,10
(2) 分组如何优先取A部门的数据?这里想到的是:增加一个字段来区分是否是A部门,增加字段is_market(为0表示为A部门)如下图:
这样可以对is_market字段进行排序,就能够优先取A部门的数据,依照上一步来对SQL进行改写。
解决方案
(1)MySQL5.5版本
-- MySQL5.5
SELECT * FROM ( SELECT cid,cphone,addtime,is_market FROM crm_test ORDER BY is_market, addtime ) AS a GROUP BY cphone LIMIT 0,10
MySQL5.5实现效果:
MySQL5.7实现效果:
由实现效果可以看出,5.7版本 手机号为“120”的数据并没有优先获取A部门的数据,并没有达到预期的效果。
(2)MySQL5.7版本
-- MySQL5.7
SELECT * FROM ( SELECT cid,cphone,addtime,is_market FROM crm_test ORDER BY is_market, addtime LIMIT 999999) AS a GROUP BY cphone LIMIT 0,10
MySQL5.7实现效果(MySQL5.5效果相同):
方案(1)为何MySQL5.5与MySQL5.7会有不同的结果?
(1)查看方案(1)这条SQL在不同版本下的执行计划
MySQL5.5
MySQL5.7
通过对比发现5.7版本的MySql在执行这条sql时缺少了一个derived操作,通过查阅相关资料了解到MySql 5.7对子查询进行了优化,认为子查询中的order by可以进行忽略。
总结
总结就是,遇到复杂的SQL,不要怕,一步一步来,一点一点拆分需求,盘它!!!
相关文章
- Mysql授权允许远程访问解决Navicat for MySQL连接mysql提示客户端不支持服务器请求的身份验证协议;考虑升级MySQL客户端
- 【MySQL】删除大量数据的具体实现
- 【MySQL】mysql optimize table
- 【Mysql】初识MySQL
- MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
- 大数据量下MySQL插入方法的性能比较
- mysql远程连接数据库很慢
- MySQL(Navicat)运行.sql文件时报错:[Err] 2006 - MySQL server has gone away 的解决方法
- Atlas实现MySQL大表部署读写分离
- mysql 主主复制(双主复制)+ 配置KEEPALIVED实现热备
- mysql启动时报错:Starting MySQL... ERROR! The server quit without updating PID file (/opt/mysql/data/mysql.pid) 的解决方法
- thinkphp6:访问多个mysql数据源(thinkphp6.0.5 / php 7.4.9)
- MySQL 查询速度慢与性能差的原因与解决方法
- MySQL 是如何实现四大隔离级别的?
- Python MySQL - mysql-connector 驱动
- Mysql 关闭日志记录
- MySQL Study之--Mysql无法启动“mysql.host”
- PostgreSQL的学习心得和知识总结(一百一十五)|词法级自上而下完美实现MySQL数据库的 反引号 的实现方案
- mysql sql语句大全(MySQL语句 整理一)
- mysql 批量更新与批量更新多条记录的不同值实现方法 (转)
- 如何实现MySQL表数据随机读取?从mysql表中读取随机数据
- MySql查询的生命周期和性能优化思路
- entity framework mysql dev set