首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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 · 244 天前 · 4833 次点击
    这是一个创建于 244 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    67 回复  |  直到 2019-05-28 13:02:38 +08:00
    tairan2006
        1
    tairan2006   244 天前 via Android
    答案是用 Python
    lihongjie0209
        2
    lihongjie0209   244 天前   ♥ 1
    不懂 sql 的话直接在代码里实现.
    leriou
        3
    leriou   244 天前
    case when
    DefoliationM
        4
    DefoliationM   244 天前 via Android
    很简单 使用游标
    ditie
        5
    ditie   244 天前
    @tairan2006 并不会呀。。。
    ditie
        6
    ditie   244 天前
    @lihongjie0209 代码里更不会了。。。
    Cat73
        7
    Cat73   244 天前
    MySQL 有 count,有 limit,麻烦点的思路可以先查记录的 id,然后 where id in ( ... )
    ditie
        8
    ditie   244 天前
    @leriou case when 我会,但怎么表示前 20%这种分布?怎么进行总排序和组内排序?
    ditie
        9
    ditie   244 天前
    @DefoliationM 游标。。。我百度了下都没明白。。。
    ditie
        10
    ditie   244 天前
    @Cat73 想想就头大呀大佬
    Huelse
        11
    Huelse   244 天前
    呃,我的理念是,任何多余的 where 条件都不写,全部交给语言去处理
    ditie
        12
    ditie   244 天前
    @Huelse 我已经听不懂了啊大佬
    francis59
        13
    francis59   244 天前
    太复杂的话要么写程序分析,要么复制到 excel 里用公式分析,excel 有不少统计分析的公式
    Alexhohom
        14
    Alexhohom   244 天前
    前 20%可以在代码里实现
    thedog
        15
    thedog   244 天前
    用 rank() over(partition by ....)
    您可以搜一下这个东西的用法
    thedog
        16
    thedog   244 天前
    哦,没有 row_number,那当我没说。。。
    ditie
        17
    ditie   244 天前
    @francis59 就是想后台 sql 直接出结果,前端网页就查看
    ditie
        18
    ditie   244 天前
    @thedog 给热心的你点赞
    ditie
        19
    ditie   244 天前
    @Alexhohom 是指什么代码呀,我前端似乎是 nodejs, 数据库就是 mysql 5.7
    lolizeppelin
        20
    lolizeppelin   243 天前   ♥ 1
    over 是窗口函数 mysql 8.0 mariadb 10.2 以后支持
    zeraba
        21
    zeraba   243 天前 via Android
    搜索 mysql 添加行号,有了行号有序的列表实现这个需求应该很简单了
    Takamine
        22
    Takamine   243 天前 via Android
    换 postgerSQL。:doge:
    Takamine
        23
    Takamine   243 天前 via Android
    @Takamine postgreSQL。_(:з」∠)_
    sinchuan
        24
    sinchuan   243 天前 via iPhone
    存储过程。尽量语句分开写,方便日后有变更。
    Umenezumi
        25
    Umenezumi   243 天前
    求总 Count 然后根据需要 when case
    zxcslove
        26
    zxcslove   243 天前 via Android
    插句话,假设有并列名次遇到区段边界如何处理?
    ditie
        27
    ditie   243 天前
    @zxcslove 脑壳痛。。。问到了这么尖锐的问题。。
    ditie
        28
    ditie   243 天前
    @lolizeppelin 5.7 版本呀,我倒想换呢,无奈我说了不算
    ditie
        29
    ditie   243 天前
    @Takamine 抓住一个吉他手
    ditie
        30
    ditie   243 天前
    @zeraba。。。请问有了行号之后该怎么做
    ditie
        31
    ditie   243 天前
    @sinchuan mysql 不是存储过程就是个笑话么。。
    ditie
        32
    ditie   243 天前
    @Umenezumi 麻烦给点具体语句示例
    acehow
        33
    acehow   243 天前 via Android
    MySQL8 支持 over 开窗函数。
    ditie
        34
    ditie   243 天前
    @acehow 无奈我的 是 5.7 版本呀
    webdisk
        35
    webdisk   243 天前
    弄完之后发现自己的绩效是 C
    strcmp
        36
    strcmp   243 天前
    redis zset
    zander1024
        37
    zander1024   243 天前
    @ditie mysql 存储不是笑话... 代码明明很好实现你一定要数据库实现那就存储,游标吧
    ditie
        38
    ditie   243 天前
    @zander1024 真心求教下,这个“代码”是指什么,怎么个写法呢?我是真的不会呀
    ditie
        39
    ditie   243 天前
    @webdisk 整个人都不好了
    ditie
        40
    ditie   243 天前
    @strcmp 这又是个什么路子,大佬再给点清晰的指导
    Alexhohom
        41
    Alexhohom   243 天前
    @ditie #19 比如你根据一些需求排序后,你的 query 里会有 count 属性,然后代码里想要控制多少数目都行。
    Alexhohom
        42
    Alexhohom   243 天前
    @ditie #40 想要分月度就 group by month 分部门就 group by department 同时 group by month,department
    ditie
        43
    ditie   243 天前
    @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
        44
    Alexhohom   243 天前
    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
        45
    ditie   243 天前
    @Alexhohom 完了,这两条我都没看明白 - [email protected] 。第一个点是用来实现什么效果的呢?第二个 count 我还是不懂是指什么,count(*) 这样的记录数?
    Alexhohom
        46
    Alexhohom   243 天前
    @ditie #45 1. 就相当于 sql 里面的 if 语句, 如果考核表没有记录,那么 sum(kh.score)+100=100,发现这样的记录使其 total=-1。
    2. 第二个就是你执行 query 后,没有报错会返回一个 result (我刚刚查的,没用过 nodejs ),result 中应该有 count 相关属性吧。result.count 这类的。
    ditie
        47
    ditie   243 天前
    @Alexhohom 嗯,第一点我知道 sql 这么写执行后的结果,但这个结果和我的需求没关系呀,还是不能分出百分比然后赋值;第二点这个返回的 result 不就是后台执行 sql 的结果么?你的意思是 sql 不动了、在前台用代码来实现分出百分比然后赋值的效果?然而这个前台的代码我也不会。。。
    Alexhohom
        48
    Alexhohom   243 天前
    @ditie #47 对的,sql 语句排序不行就用后台代码实现,换一种思路。第一个不是解决让其他 70 个人的值一致嘛
    mmdsun
        49
    mmdsun   243 天前 via Android
    最终显示效果是怎么样的?这样?
    (月 score 部门,月 score 全体,绩效)
    xuanbg
        50
    xuanbg   243 天前
    分 3 次操作就简单了呀,先不要管什么 ABC,把数据存进去。然后再把排序在前 20%的更新成 A,最后把倒序前 10%更新成 C。
    楼上那些无脑查询让代码处理的,就没遇到过数据量太大导致磁盘 IO 和网络 IO 飞起么?
    DRcoding
        51
    DRcoding   243 天前
    有了序号就简单了:
    SELECT (@i := @i + 1) as ord FROM XXXX ,(SELECT @i := 0) i ORDER BY .....
    ratel
        52
    ratel   243 天前
    可以增加另外的统计表,不建议太复杂的 SQL
    ditie
        53
    ditie   243 天前
    @Alexhohom 昨晚睡觉了。。。这么操作数据是一致成-1 了,但是并不是一致成月度日期呀
    ditie
        54
    ditie   243 天前
    @mmdsun 是的,我想要的数据是结果是 月度,部门,员工 ID,score,部门内排名,绩效(根据部门内排名的百分比分布来给 ABC ),全公司排名
    ditie
        55
    ditie   243 天前
    @DRcoding 嗯,我通过这个实现了部门内部的排名,还差两个:一个是分出百分比来给绩效、第二个是全公司排名
    ditie
        56
    ditie   243 天前
    @xuanbg 分三次,是要写存储过程么,这个又超出了我的技术水平。。。
    ditie
        57
    ditie   243 天前
    @ratel 那就是楼上说的分步骤操作?
    Beeethoven
        58
    Beeethoven   243 天前
    为什么一定要一个 sql 查出来呢,后台代码实现要简单很多而且性能高很多,一次把需要的数据全部查出来,然后分类输出就好了
    Beeethoven
        59
    Beeethoven   243 天前
    java 的话就新建一个 examine 实体,department,date,userid,score 四个属性,再加一个 rank 来分类,根据条件查出来然后循环赋值 rank 给前端显示需要的结果。

    插入到新表中就用代码 insert 回去就好了
    Alexhohom
        60
    Alexhohom   243 天前
    @ditie #53 order by month,total 这样是先按月度排序,然后按 total 排序。
    xuanbg
        61
    xuanbg   243 天前
    @ditie 其实是 4 次,1 次 insert,3 次 update,不需要存储过程,当然,你把这 3 个操作写到一个存储过程里面也是可以的。
    tudouxiong
        62
    tudouxiong   243 天前 via Android
    窗口函数,需要 mysql 8 以后
    LeeSeoung
        63
    LeeSeoung   242 天前
    先查一遍总数 按分数倒序排 ,然后 case when 判断 rownum<total*0.2 则 A ……这样可以不
    ditie
        64
    ditie   242 天前
    @Beeethoven 是的,现在打算分步骤了,不打算一步到位。说实话,java 我一点都不会
    ditie
        65
    ditie   242 天前
    @Alexhohom 好的,后面我试试
    ditie
        66
    ditie   242 天前
    @xuanbg 那我试一下,确实还是分步骤好操作
    ditie
        67
    ditie   242 天前
    @LeeSeoung rownum<total*0.2 这个方式好,厉害了,谢谢大佬
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1865 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 05:11 · PVG 13:11 · LAX 21:11 · JFK 00:11
    ♥ Do have faith in what you're doing.