› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
ditie
V2EX  ›  MySQL

小白求教: mysql 怎么实现排序后新增一列并分区段赋值,比如分数排名前 20%的就是绩效 A,后 10%的就是绩效 C

  •  
  •   ditie · May 26, 2019 · 8928 views
    This topic created in 2718 days ago, the information mentioned may be changed or developed.

    比如数据表 kaohe 的字段有 id,department,date,userid,score。

    需求有三个: 1、怎么根据 score 在一个语句里分月度、分部门进行组内排序,以及当月全体排序?

    2、怎么能多一列来显示自动分布的绩效?排名前 20%的就是绩效 A,后 10%的就是绩效 C

    3、怎么把这个排序和新增后的绩效结果全部插入到一个新表里?

    我是 MySQL 数据库,木有 row_number ()函数

    67 replies  •  2019-05-28 13:02:38 +08:00
    keenkiller
    keenkiller
    May 26, 2019 via Android
    1
    答案是用 Python
    lihongjie0209
    lihongjie0209
    May 26, 2019❤️1
    2
    不懂 sql 的话直接在代码里实现.
    leriou
    leriou
    May 26, 2019
    3
    case when
    DefoliationM
    DefoliationM
    May 26, 2019 via Android
    4
    很简单 使用游标
    ditie
    ditie
    OP
    May 26, 2019
    5
    @tairan2006 并不会呀。。。
    ditie
    ditie
    OP
    May 26, 2019
    6
    @lihongjie0209 代码里更不会了。。。
    Cat73
    Cat73
    May 26, 2019
    7
    MySQL 有 count,有 limit,麻烦点的思路可以先查记录的 id,然后 where id in ( ... )
    ditie
    ditie
    OP
    May 26, 2019
    8
    @leriou case when 我会,但怎么表示前 20%这种分布?怎么进行总排序和组内排序?
    ditie
    ditie
    OP
    May 26, 2019
    9
    @DefoliationM 游标。。。我百度了下都没明白。。。
    ditie
    ditie
    OP
    May 26, 2019
    10
    @Cat73 想想就头大呀大佬
    Huelse
    Huelse
    May 26, 2019
    11
    呃,我的理念是,任何多余的 where 条件都不写,全部交给语言去处理
    ditie
    ditie
    OP
    May 26, 2019
    12
    @Huelse 我已经听不懂了啊大佬
    francis59
    francis59
    May 26, 2019
    13
    太复杂的话要么写程序分析,要么复制到 excel 里用公式分析,excel 有不少统计分析的公式
    Alexhohom
    Alexhohom
    May 26, 2019
    14
    前 20%可以在代码里实现
    thedog
    thedog
    May 26, 2019
    15
    用 rank() over(partition by ....)
    您可以搜一下这个东西的用法
    thedog
    thedog
    May 26, 2019
    16
    哦,没有 row_number,那当我没说。。。
    ditie
    ditie
    OP
    May 26, 2019
    17
    @francis59 就是想后台 sql 直接出结果,前端网页就查看
    ditie
    ditie
    OP
    May 26, 2019
    18
    @thedog 给热心的你点赞
    ditie
    ditie
    OP
    May 26, 2019
    19
    @Alexhohom 是指什么代码呀,我前端似乎是 nodejs, 数据库就是 mysql 5.7
    lolizeppelin
    lolizeppelin
    May 26, 2019❤️1
    20
    over 是窗口函数 mysql 8.0 mariadb 10.2 以后支持
    zeraba
    zeraba
    May 26, 2019 via Android
    21
    搜索 mysql 添加行号,有了行号有序的列表实现这个需求应该很简单了
    Takamine
    Takamine
    May 26, 2019 via Android
    22
    换 postgerSQL。:doge:
    Takamine
    Takamine
    May 26, 2019 via Android
    23
    @Takamine postgreSQL。_(:з」∠)_
    sinchuan
    sinchuan
    May 26, 2019 via iPhone
    24
    存储过程。尽量语句分开写,方便日后有变更。
    Umenezumi
    Umenezumi
    May 26, 2019
    25
    求总 Count 然后根据需要 when case
    zxcslove
    zxcslove
    May 26, 2019 via Android
    26
    插句话,假设有并列名次遇到区段边界如何处理?
    ditie
    ditie
    OP
    May 26, 2019
    27
    @zxcslove 脑壳痛。。。问到了这么尖锐的问题。。
    ditie
    ditie
    OP
    May 26, 2019
    28
    @lolizeppelin 5.7 版本呀,我倒想换呢,无奈我说了不算
    ditie
    ditie
    OP
    May 26, 2019
    29
    @Takamine 抓住一个吉他手
    ditie
    ditie
    OP
    May 26, 2019
    30
    @zeraba。。。请问有了行号之后该怎么做
    ditie
    ditie
    OP
    May 26, 2019
    31
    @sinchuan mysql 不是存储过程就是个笑话么。。
    ditie
    ditie
    OP
    May 26, 2019
    32
    @Umenezumi 麻烦给点具体语句示例
    acehow
    acehow
    May 26, 2019 via Android
    33
    MySQL8 支持 over 开窗函数。
    ditie
    ditie
    OP
    May 26, 2019
    34
    @acehow 无奈我的 是 5.7 版本呀
    webdisk
    webdisk
    May 26, 2019
    35
    弄完之后发现自己的绩效是 C
    strcmp
    strcmp
    May 26, 2019
    36
    redis zset
    zander1024
    zander1024
    May 26, 2019
    37
    @ditie mysql 存储不是笑话... 代码明明很好实现你一定要数据库实现那就存储,游标吧
    ditie
    ditie
    OP
    May 26, 2019
    38
    @zander1024 真心求教下,这个“代码”是指什么,怎么个写法呢?我是真的不会呀
    ditie
    ditie
    OP
    May 26, 2019
    39
    @webdisk 整个人都不好了
    ditie
    ditie
    OP
    May 26, 2019
    40
    @strcmp 这又是个什么路子,大佬再给点清晰的指导
    Alexhohom
    Alexhohom
    May 26, 2019
    41
    @ditie #19 比如你根据一些需求排序后,你的 query 里会有 count 属性,然后代码里想要控制多少数目都行。
    Alexhohom
    Alexhohom
    May 26, 2019
    42
    @ditie #40 想要分月度就 group by month 分部门就 group by department 同时 group by month,department
    ditie
    ditie
    OP
    May 26, 2019
    43
    @Alexhohom group by 我会了。现在碰到俩问题:

    背景:数据表 kaohe 的字段有 id,department,date,userid,score。数据表 staff 有 userid,username,department

    1、我有 100 个员工,当月可能只有 30 条员工的考核记录,那么最后 group by 员工号统计时另外 70 人就没有月度(KH.date)的值,请问该怎么让这 70 个人的结果里也有一致的月度值。语句是这样:
    select KH.date,ST.userid,St.username,sum(KH.score)+100 as total
    from staff as ST
    left join on kaohe as KH on ST.userid=KH.userid
    group by KH.date,KH.userid


    2、count 属性该怎么体现或者加工出来,每个月给前 20%的人赋值为 A,后 10%的人为 C,其他人为 B
    Alexhohom
    Alexhohom
    May 26, 2019
    44
    1. sql server 中可以这样(case sum(KH.score)+100 when 100 then -1 else sum(KH.score)+100 end) as total,其中-1 是你自己确定的。
    2. count 在代码中执行完 query 会有一个返回吧,就是你需要从数据库中取值的那个变量。count 可以帮助你遍历你的查询
    ditie
    ditie
    OP
    May 26, 2019
    45
    @Alexhohom 完了,这两条我都没看明白 - -@ 。第一个点是用来实现什么效果的呢?第二个 count 我还是不懂是指什么,count(*) 这样的记录数?
    Alexhohom
    Alexhohom
    May 26, 2019
    46
    @ditie #45 1. 就相当于 sql 里面的 if 语句, 如果考核表没有记录,那么 sum(kh.score)+100=100,发现这样的记录使其 total=-1。
    2. 第二个就是你执行 query 后,没有报错会返回一个 result (我刚刚查的,没用过 nodejs ),result 中应该有 count 相关属性吧。result.count 这类的。
    ditie
    ditie
    OP
    May 26, 2019
    47
    @Alexhohom 嗯,第一点我知道 sql 这么写执行后的结果,但这个结果和我的需求没关系呀,还是不能分出百分比然后赋值;第二点这个返回的 result 不就是后台执行 sql 的结果么?你的意思是 sql 不动了、在前台用代码来实现分出百分比然后赋值的效果?然而这个前台的代码我也不会。。。
    Alexhohom
    Alexhohom
    May 26, 2019
    48
    @ditie #47 对的,sql 语句排序不行就用后台代码实现,换一种思路。第一个不是解决让其他 70 个人的值一致嘛
    mmdsun
    mmdsun
    May 26, 2019 via Android
    49
    最终显示效果是怎么样的?这样?
    (月 score 部门,月 score 全体,绩效)
    xuanbg
    xuanbg
    May 27, 2019
    50
    分 3 次操作就简单了呀,先不要管什么 ABC,把数据存进去。然后再把排序在前 20%的更新成 A,最后把倒序前 10%更新成 C。
    楼上那些无脑查询让代码处理的,就没遇到过数据量太大导致磁盘 IO 和网络 IO 飞起么?
    DRcoding
    DRcoding
    May 27, 2019
    51
    有了序号就简单了:
    SELECT (@i := @i + 1) as ord FROM XXXX ,(SELECT @i := 0) i ORDER BY .....
    ratel
    ratel
    May 27, 2019
    52
    可以增加另外的统计表,不建议太复杂的 SQL
    ditie
    ditie
    OP
    May 27, 2019
    53
    @Alexhohom 昨晚睡觉了。。。这么操作数据是一致成-1 了,但是并不是一致成月度日期呀
    ditie
    ditie
    OP
    May 27, 2019
    54
    @mmdsun 是的,我想要的数据是结果是 月度,部门,员工 ID,score,部门内排名,绩效(根据部门内排名的百分比分布来给 ABC ),全公司排名
    ditie
    ditie
    OP
    May 27, 2019
    55
    @DRcoding 嗯,我通过这个实现了部门内部的排名,还差两个:一个是分出百分比来给绩效、第二个是全公司排名
    ditie
    ditie
    OP
    May 27, 2019
    56
    @xuanbg 分三次,是要写存储过程么,这个又超出了我的技术水平。。。
    ditie
    ditie
    OP
    May 27, 2019
    57
    @ratel 那就是楼上说的分步骤操作?
    Beeethoven
    Beeethoven
    May 27, 2019
    58
    为什么一定要一个 sql 查出来呢,后台代码实现要简单很多而且性能高很多,一次把需要的数据全部查出来,然后分类输出就好了
    Beeethoven
    Beeethoven
    May 27, 2019
    59
    java 的话就新建一个 examine 实体,department,date,userid,score 四个属性,再加一个 rank 来分类,根据条件查出来然后循环赋值 rank 给前端显示需要的结果。

    插入到新表中就用代码 insert 回去就好了
    Alexhohom
    Alexhohom
    May 27, 2019
    60
    @ditie #53 order by month,total 这样是先按月度排序,然后按 total 排序。
    xuanbg
    xuanbg
    May 27, 2019
    61
    @ditie 其实是 4 次,1 次 insert,3 次 update,不需要存储过程,当然,你把这 3 个操作写到一个存储过程里面也是可以的。
    tudouxiong
    tudouxiong
    May 27, 2019 via Android
    62
    窗口函数,需要 mysql 8 以后
    LeeSeoung
    LeeSeoung
    May 27, 2019
    63
    先查一遍总数 按分数倒序排 ,然后 case when 判断 rownum<total*0.2 则 A ……这样可以不
    ditie
    ditie
    OP
    May 28, 2019
    64
    @Beeethoven 是的,现在打算分步骤了,不打算一步到位。说实话,java 我一点都不会
    ditie
    ditie
    OP
    May 28, 2019
    65
    @Alexhohom 好的,后面我试试
    ditie
    ditie
    OP
    May 28, 2019
    66
    @xuanbg 那我试一下,确实还是分步骤好操作
    ditie
    ditie
    OP
    May 28, 2019
    67
    @LeeSeoung rownum<total*0.2 这个方式好,厉害了,谢谢大佬
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1313 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 67ms · UTC 21:05 · PVG 05:05 · LAX 13:05 · JFK 16:05
    ♥ Do have faith in what you're doing.