zoukankan      html  css  js  c++  java
  • SQL中group by问题

    在使用sql语句中,我们常常使用group by加聚合函数来分组并聚合,从而实现某些需求。然而,不正确地使用group by和聚合函数,会带来非常隐晦的问题。

    有这样一个需求:对表进行分组后找出用户首次获得最高分数的那条记录的全部信息。

    为此,我创建了一张记录用户闯关信息的表,记录了用户在不同课程领域的不同关卡下获得的分数信息:

    pass_log表

    最开始我觉得很简单,sql是这样写的:

    select pl.id, pl.user_id, pl.course_id, pl.pass_id, max(pl.total_score)
    from pass_log pl
    group by pl.user_id, pl.course_id, pl.pass_id;

    结果是这样的:

     大家发现端倪没有?分组和聚合的结果都是对的,但是id却是错的,正确的id应该分别是3、5啊!但是为什么取的是1、4呢?因为它取的是分组后的第一条记录的id!那应该怎么改过来呢?我的想法是先获取分组后的信息和最高分,再和原表进行内关联:

    select p.id, p.user_id, p.course_id, p.pass_id, p.total_score
    from pass_log p
    join (
        select pl.user_id, pl.course_id, pl.pass_id, max(pl.total_score) maxTotalScore
        from pass_log pl
        group by pl.user_id, pl.course_id, pl.pass_id) t
    on p.user_id = t.user_id and p.course_id = t.course_id and p.pass_id = t.pass_id
    where p.total_score = maxTotalScore
    group by p.user_id, p.course_id, p.pass_id;

    我在最外层又加group by的原因是用户可能在同一个关卡里获得多次最高分,而我只想要首次获得最高分数的那条记录,最后结果是正确的,如图:

    后来我想数据查出来的都是错的,为什么mysql不报错呢?这样不是坑我?后来发现还真的会出现报错的情况,执行sql观察:

    select @@global.sql_mode;

    如果结果中含有ONLY_FULL_GROUP_BY的话,执行我的第一条sql语句就会报错,想要不报错的话就要把pl.id改为any_value(pl.id),但是结果还是取分组后的第一个id,并不是我想要的结果。

    其实我最后想表达的是,如果你的group by语句在一个环境下没问题,但是在其它环境下就报异常,那会不会是你group by用错了?

  • 相关阅读:
    枚举类型或运算
    设置字体同时为粗体、斜体
    批量处理任务进度条控制—基于BackgroundWorker
    PyCharm终端执行python脚本报错:ModuleNotFoundError: No module named 'lib.apilib'
    PyCharm用pytest模式执行python脚本不生成allure测试报告
    Python3+Appium基于安卓平台的app自动化
    JMeter上一个接口返回数据作为下一个接口的参数应用
    JMeter安装及语言切换
    Python之序列化和反序列化
    Requests库发送post请求,传入接口参数后报JSON parse error
  • 原文地址:https://www.cnblogs.com/liuzhulin/p/12229976.html
Copyright © 2011-2022 走看看