首页   注册   登录
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
V2EX  ›  MySQL

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

  •  
  •   ditie · 32 天前 · 4025 次点击
    这是一个创建于 32 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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