SQL 艺术:分组去重排序关联

事情交代

在日常唠嗑前先简单说一下本文想要记录的一次 MySQL 技术回顾:两张表,对其中一张表进行分组去重后,对结果集进行排序,然后关联另一张表得到最终的结果集

当时推翻重来了几次,从中也学到不少 SQL 知识,因此有必要写成文章系统的给自己一个交代。

OK,接下来先谈些感悟。不喜的请略过,谢谢

日常唠嗑

自从来到这家公司之后,一直在维护后台系统,其中包括一些旧版页面的整改、增加新功能等等。熟悉一个已有的业务逻辑较复杂的系统,我个人是没有什么经验的。大二进入老师的实验室后一直做的是外包项目,每一个外包项目都是全新的,都是自己去从头搭建,所以其中涉及到的代码我都非常熟悉。

因此刚来的时候,拿到这个项目的源代码,开始去了解熟悉,发现其中用到的语言版本、框架版本等都普遍偏低,非常不适应,心里也不免有不少抱怨(当我看完李笑来先生的《把时间当做朋友》后,深刻明白抱怨一点积极意义都没有,反而会打乱自己。现在遇事也会成熟不少,更多的是去积极的看待事物。改变自己挺难的,但改变自己很重要)。最初一段时间,很不情愿的去看这个项目的先辈们写下的对于现在来说不太优秀的代码,然后对于组长指派的迭代任务我也是依样画葫芦的在原有系统上增加修改。

觉得很多时候都在和老系统的代码作斗争,修 bug,加补丁,等等。

没有思考,当然也不会有沉淀,更别提进步。 我带着一种不屑、不愿的态度接手项目,在经过一段消极的工作之旅后,我通过阅读书籍带给我的思考对自己审视了一番。

其实对于工程师而言,一个很好的练习,就是试着重构一个有很多问题的老系统。老系统在很多时候,因为设计初期很多需求不一样,资源和约束也不一样,随着时间推移,才慢慢显得不足。而当你了解一个系统要做的东西,以及所有的缺陷和坑,试着去思考:如果是你来重新设计这个系统,你会怎么做?一定会有哪些选择?一定会避免哪些选择?
这样的练习,在脑海里一遍遍地过,即使你没有时间和精力去真的重构,也会对你能力的提高有很大的帮助。而有机会的时候,从一些小的地方着手,试图一点点地在力所能及的范围内改进系统。这比鄙视旧系统,然后不断写出更烂的代码、把系统变得更糟糕要好很多。

这段话来自微信公众号:嘀嗒嘀嗒,文章题为《为什么有的程序员觉得自己是个打杂的?

当时看到这标题的时候总感觉是写给我的,不过现在明白醒悟也不晚,幸运如我,不是吗 :)

唠嗑结束了,接下来是这次的正文。

需求场景

事情是这样的,上周五运营人员提了一个需求(仅为一个例子):希望在用户列表页面能对登录时间进行过滤排序,比如想要看到3月1日至3月2日登录过的用户,且根据这段时间内用户的登录时间进行降序排列。结合数据库的情况,这个需求要用到两张表(一个用户表:user,一个用户登录记录表:user_login_record)。

user

user_id nick
1 amy
2 bob

user_login_record

id user_id login_time
1 1 2017-03-01 00:00:00
2 1 2017-03-01 20:00:00
3 2 2017-03-01 05:00:00
4 2 2017-03-01 09:00:00
5 2 2017-03-01 16:00:00

心路历程

如果某个用户在过滤的时间段内登录过两次及以上,那么一定会遇到需要分组去重的问题。

版本1.0

执着于使用 DISTINCT 来完成去重的操作,但这样只能对某一列进行去重,且无法列出其他列,也就没法在一个 SQL 中再进行排序操作。

SELECT
    DISTINCT user_id
FROM
    user_login_record
WHERE
    login_time BETWEEN '2017-03-01' AND '2017-03-02'
GROUP BY
    user_id
版本2.0

经人提醒,可以使用 聚合函数 来达到去重的效果。

SELECT
    user_id, MAX(login_time) as max_login_time
FROM
    user_login_record
WHERE
    login_time BETWEEN '2017-03-01' AND '2017-03-02'
GROUP BY
    user_id
ORDER BY
    max_login_time DESC

这里拿到了已去重排好序的满足过滤条件的用户 ID 以及那个时间段内最近一次登录时间,接下来就是将 user 表中用户信息获取到即可

user_id max_login_time
1 2017-03-01 20:00:00
2 2017-03-01 16:00:00

可以通过后端脚本将 user_id 拼接起来作为查询条件

SELECT
    user_id,
    nick
FROM
    user
WHERE
    user_id IN (1, 2)
ORDER BY
    FIELD(user_id, 1, 2)
user_id nick
1 amy
2 bob

由于两个结果集的顺序是一样的,因此登录时间也是一一对应的,所以对其中一个结果集循环,对应另一个结果集中索引对应的值合并。

MySQL 知识点:FIELD

  • 作用:自定义排序

  • 格式

FIELD(value, str1, str2...)
  • 场景

由于 MySQL 并不会按 IN 中传入的参数顺序输出结果集,因此需要用到 FIELD 来自定义排序,只需传入的参数与 IN 中传入的参数完全相同即可

SQL 语句有多重要~

在减少数据库连接与减少数据库执行负担两者间进行权衡。运用得好可以提升性能,减少代码。总之,多思考。

晚安,各位,床上那位催着睡觉了。。。


首发于个人博客 StephenCode

同步在:

知乎专栏:黑白之间

简书专题:黑白之间

SegmentFault 专栏:黑白之间

微信公众号:黒白之间

wechat.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容