V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 换工作是一件经过深思熟虑的严肃事情
• 频繁换工作是 loser 做的事情
• 公司应该提供给员工尽可能好的条件
• 这里不欢迎苦大仇深的公司
• 原则上这里不欢迎猎头发帖,除非是懂技术的猎头
• 如果你自己从来没有从期权上赚过钱,就不要在招聘时强调期权
• 招聘时请尽量给出薪酬范围
• 求职时请附上自己的薪酬要求
• 说话前经过足够的思考是好习惯
• 上传一个有意义的头像会更体现你们公司的品牌和诚意
• 请不要在 1 天的时间内在酷工作节点发布超过 3 个主题
• 在不同节点下发布内容相同的主题这种行为不科学
vegetableChick
V2EX  ›  酷工作

MYSQL 求每个月的 topN 问题

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

    有如下的一个表

    months  contact   COUNT
    202007  asdas      45
    202007  maouse      1
    202007  RORC YANG   1
    202007  RORG        2
    202007  ROR         5
    202008  SARINA      6
    202008  MBL         2
    202008  MLT         2
    ...
    

    我如何能获取到每个月的top2?

    希望得到的结果:

    months  contact   COUNT
    202007  asdas      45
    202007  ROR         5
    202008  SARINA      6
    202008  MBL         2
    ...
    

    当前 mysql 版本 5.6

    请各位大佬帮忙看一下, 感谢!

    18 条回复    2021-03-31 12:59:16 +08:00
    beichenhpy
        1
    beichenhpy   246 天前
    select * from a A where (select cout(*) from a B where A.months = B.months and A.count >= B.count) <= 2
    beichenhpy
        2
    beichenhpy   246 天前
    count(*) 拼错了,还有你发错分区了吧。。
    Nostalgiaaaa
        3
    Nostalgiaaaa   246 天前
    SELECT *
    FROM
    (SELECT *,
    ROW_NUMBER() over(partition by months
    ORDER BY COUNT desc) ranks
    FROM table ) a
    WHERE a.ranks IN (1, 2)
    ahmcsxcc
        4
    ahmcsxcc   246 天前
    @Nostalgiaaaa #3 mysql 5.6 不支持这个语法
    beichenhpy
        5
    beichenhpy   246 天前
    @ahmcsxcc 是的,mysql 这个需求比较难弄啊,感觉要写存储过程。。不然就要在代码里写了。。还是 PgSql 函数多
    vegetableChick
        6
    vegetableChick   246 天前
    @beichenhpy 感谢回复, 但是好像是空结果
    vegetableChick
        7
    vegetableChick   246 天前
    @Nostalgiaaaa 谢谢回复, 我的 mysql 版本比较旧了 还是 5.6
    beichenhpy
        8
    beichenhpy   246 天前
    @vegetableChick
    -- part 为 month 对应用谁分组
    select z.month,z.count,z.rank
    from
    (select
    x.*,
    @rownum := @rownum + 1,
    if(@part = x.month,
    @r := @r + 1,
    @r := 1) as rank,
    @part := x.month
    from
    (
    select
    *
    from
    test e
    order by
    e.count,e.`month` desc) x,
    (
    select
    @rownum := 0,
    @part := null,
    @r := 0) rt)z
    where z.rank in (1,2)
    beichenhpy
        9
    beichenhpy   246 天前
    @vegetableChick
    ```
    -- part 为 month 对应用谁分组
    -- 注意 order by 的顺序
    select z.month,z.count,z.rank
    from
    (select
    x.*,
    @rownum := @rownum + 1,
    if(@part = x.month,@r := @r + 1,@r := 1) as rank,
    @part := x.month
    from
    (
    select
    *
    from
    test e
    order by
    e.month asc,e.count desc) x,
    (
    select
    @rownum := 0,
    @part := null,
    @r := 0) rt)z
    where z.rank in (1,2)
    ```
    vegetableChick
        10
    vegetableChick   246 天前
    @beichenhpy nb !但是没太看懂, 求大佬讲一下思路
    vegetableChick
        11
    vegetableChick   246 天前
    @beichenhpy 结果出来了, 但是没懂原理
    beichenhpy
        12
    beichenhpy   246 天前
    @vegetableChick 就是实现了一遍 over(partition by month)
    vegetableChick
        13
    vegetableChick   246 天前
    @beichenhpy 我怎么老觉得不需要 下面的这个`select`, 看上去上面把这些变量又初始化了。 但是去掉就错了
    ```
    select
    @rownum := 0,
    @part := null,
    @r := 0) rt)z
    ```
    beichenhpy
        14
    beichenhpy   246 天前
    @vegetableChick 下面是初始化的。。不要去掉
    beichenhpy
        15
    beichenhpy   246 天前
    @vegetableChick 看一下 mysql 执行顺序。。from 是先执行的
    vegetableChick
        16
    vegetableChick   246 天前
    @beichenhpy 嗯 感谢,学习一下
    more1sec
        17
    more1sec   246 天前
    程序代码处理吧。。。别用子查询
    zzz686970
        18
    zzz686970   244 天前
    @beichenhpy
    我测试了一下,子查询里面应该是小于?而且如果 count 有重复的数字,应该换成<

    ```
    select * from t A where (select count(*) from t B where A.month = B.month and A.cnt < B.cnt) < 2

    ```
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2211 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 00:42 · PVG 08:42 · LAX 16:42 · JFK 19:42
    ♥ Do have faith in what you're doing.