zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

MySQL 实现不同分组取不同值

mysql 实现 不同 分组
2023-09-11 14:19:17 时间

简述

最近做项目过程中遇到这样一个需求:实现不同分组取不同的值(类似先排序再分组),具体需求如下:

(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部门的数据,并没有达到预期的效果。

全TM的是套路 - 渣渣不足为惧(宝宝)_动图_宝宝表情

(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,不要怕,一步一步来,一点一点拆分需求,盘它!!!

蹦迪小表情                                                                                   蹦迪小表情                                                                                      蹦迪小表情