上周用户提出一个功能优化。
具体需求是这样的,对于该系统的某类型人员搜索框,
一,当用户鼠标点击搜索框但未输入搜索条件时,查询并展示出当前用户的常用联系人,并按照使用频率排序,展示前20条查询结果;
二,当用户输入了搜索条件时,按照条件模糊查询用户表全量数据(过滤系统管理员等角色),并对查询结果排序,展示前20条查询结果,排序规则:
1.与当前用户同一部门的用户优先展示
2.用户编号正序排序
首先满足第1条规则,再满足第2条规则。也就是说同一部门的用户也要按照用户编号排序。
备注:涉及的几张表都是正常的表结构设计,人员表,部门表,常用联系人表。
老实说,在接到用户需求时,我并没有想到如何实现这个需求,特别是一想到要写一个这样排序的sql语句就本能的排斥,觉得很难。
对于第一种情况的需求,相应的常用联系人查询已经有现成的接口了,用户单击鼠标触发查询后,可通过输入条件是否为空,来走不同的代码分支。主要难度在于第二种,当用户输入条件时的排序问题。
惯常思维,排序通常可以直接按照sql语法order by相关字段来排序,比如按照人员编号排序就可以直接用数据库的排序来实现,问题是如何通过order by来使得同部门的人员排在前面?
经过思考,应该立刻判断出sql语法本身很可能支持不了这种排序规则。(或者有,只是我不知道)
于是,很自然可以考虑通过查询两次的方式,最后将两次查询结果加起来(利用list的有序)。先查询同部门的人员并按照用户编号排序,如果查询结果条数n>=20条则直接返回查询结果,如果n<20条,则再查询不是同部门的人员并按照用户编号排序,查询条数为20-n,最后把两次查询结果List.add一下,就可以了。
很显然,这样的方式虽然实现了需求,但由于查询了两次,会调用两次数据库查询,要是能只用一次查询,性能会更好。
既然通过查询两次再把结果集加起来可以实现,那为什么不能使用sql语法中的union函数来实现呢?只要union函数不会打乱两次查询的结果,那就是可行的。
于是很快用union函数写出查询sql,测试后果然没问题。
于是,我便巧妙地运用union函数实现了这种特殊的排序规则。
本次开发,值得总结的是,有时候解决问题的方式可以是“不断改进”,如果不去尝试用两次查询的方式来解决,那我很可能想不到用union的方式。这种先边做边想边优化的做事方式其实在日常工作中用的非常多。
遇到问题,实在没有很好的办法,那就先用着笨办法动起来再说~_~