SQL优化之使用数学的方式优化SQL编码01

前言

笔者最近工作大多写sql为主。所以在此记录一下工作中遇到的问题和解决方案。

今天先写上一篇,之后也会将这类似的方法总结下来,发表在这里。

在特定场景下如何利用数学优化SQL编码

直接拿最近的一个需求举例,楼主习惯先写自己原先的笨方法,也是大多数人一下子就能想到的方法,然后在去写改进的方法。

好了,说下具体需求:

轻度汇总后的数据涉及到了标签打分。根据某列(数值型)的范围进行划分并打上相应的标签,并用该标签与标签评分表关联拿到评分。

看完需求后,简单啊,开搞。

为了方便,以下数据都用一个标签来讲。

  • 标签评分表一个标签对应了多个等级,(label, grade)唯一确定一条数据。如下:

    注意在我们的场景中当汇总表的total_countw 为0时,score分值也为0,并没有包含在前20%的区间中

label(标签) grade(等级) score(分值) desc( (左闭右开)
L1 A 1000 前20%
L1 B 800 20%—40%
L1 C 600 40%—60%
L1 D 400 60%—80%
L1 E 200 后20%
L1 F 0 值为0
  • 轻度汇总表table_agg:
id label(标签) total_count(该标签出现的次数)
001 L1 390
002 L1 700
003 L1 675
004 L1 5065
  1. 首先需要将数据根据百分比将数据的等级标识出来
SELECT  id
       ,label
       ,total_count 
       ,rk
       ,cnt
       ,rk / cnt as percentage 
       ,CASE WHEN total_count = 0 THEN 'F' 
             WHEN rk / cnt > 0 AND rk / cnt < 0.2 THEN 'A' 
             WHEN rk / cnt >= 0.2 AND rk / cnt < 0.4 THEN 'B' 
             WHEN rk / cnt >= 0.4 AND rk / cnt < 0.6 THEN 'C' 
             WHEN rk / cnt >= 0.6 AND rk / cnt < 0.8 THEN 'D' 
             WHEN rk / cnt >= 0.8 THEN 'E' 
        END AS grade
FROM 
(
    SELECT  id
           ,label
           ,total_count
           ,row_number() OVER (ORDER BY total_count DESC) AS rk 
           ,COUNT(*) OVER ()                              AS cnt
    FROM table_agg 
) t;

结果如下:

id label total_count rk cnt _c5 grade
004 L1 5065 1 8 0.125 A
007 L1 4078 2 8 0.25 B
002 L1 700 3 8 0.375 B
001 L1 390 4 8 0.5 C
008 L1 335 5 8 0.625 D
006 L1 201 6 8 0.75 D
005 L1 99 7 8 0.875 E
003 L1 0 8 8 1 F

然后根据(label, grade) 去关联标签评分表即可拿到对应的分值。

BUT

如果在0到1区县化分不只为5个区间呢?有时候为了让评分更加细粒度,我们可能会在0到1之前划分为100,500,甚至1000个区间!!

如果按照上面写case when的方式。。。emmm也挺好,一天啥也不用干了,泡杯茶CV大法。

但是这么做写出来的SQL别人看了会骂娘,而且也不保证区间的开闭都正确。

最重要的一点那就是:如果我的区间动态调整了,也就是说我的标签评分表更新了怎么办?人工维护吗???

非也!!下面介绍一种从数学上的方法,让你的代码由几十行,几百行都变成短短的一行。

改进

首先,在标签评分表中,如果我们的区间分为了n个,n > 50 ....甚至1000,用大写字母ABC来表示已经很难了。

所以我们换种思路,将grade使用自然升序数字:1,2,3 ... n 来表示,即:

label(标签) grade(等级) score(分值) desc( (左闭右开)
L1 1 1000 前20%
L1 2 800 20%—40%
L1 3 600 40%—60%
L1 4 400 60%—80%
L1 5 200 后20%
L1 6 0 值为0

然后重点来了,先把改完的sql列出来:

SELECT  id
       ,label
       ,total_count 
       ,rk
       ,cnt
       ,rk / cnt as percentage 
       ,CASE WHEN total_count = 0 THEN '0' ELSE ceil((rk / cnt) * 5) END AS grade
FROM 
(
    SELECT  id
           ,label
           ,total_count
           ,row_number() OVER (ORDER BY total_count DESC) AS rk 
           ,COUNT(*) OVER ()                              AS cnt
    FROM table_agg 
) t;

得到的结果为:

id label total_count rk cnt _c5 grade
004 L1 5065 1 8 0.125 1
007 L1 4078 2 8 0.25 2
002 L1 700 3 8 0.375 2
001 L1 390 4 8 0.5 3
008 L1 335 5 8 0.625 4
006 L1 201 6 8 0.75 4
005 L1 99 7 8 0.875 5
003 L1 0 8 8 1 6

然后根据(label, grade) 去关联标签评分表即可拿到对应的分值。

大家看到了,没错!重点那就是

CASE WHEN total_count = 0 THEN '0' ELSE ceil((rk / cnt) * 5) END AS grade

这里使用了ceil这个向上取整的函数,而5则是代表了划分的区间。

至此,用数学方法解决了此类场景下根据百分数多个特定区间划分的问题。

总结

真是妙蛙种子吃着妙脆角妙进了米奇妙妙屋,妙到家了

by 俩只猴

2021.01.04

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

推荐阅读更多精彩内容