以下为示例表结构,业务场景的操作均以此表进行测试

示例:数据表结构

表test字段 字段描述
id 成员
team 小组
subject1 学科
grade 得分
grade1 得分1

在这里插入图片描述

1、取每个id,两列字段值均较高的一行记录

思路:按照列字段grade,grade2的数值大小进行从高到低排序, 针对每一个主键id取出排序后的第一行数据。
下面介绍两种实现方式:

方法一:先order by +limit 再group by

group by更多的是和聚合函数一起使用,达到分组统计的效果,或者和having搭配使用对分组后的结果进行条件筛选,这里使用group by不是进行计数,而是利用了抽取第一行数据的特性。对排序后的结果进行group by 恰恰抽取到了想要grade,grade2两列值均最高的一行数据

代码示例:

select a.* from
(select * from test
order by grade desc, grade2 desc) a 
group by a.id 

运行结果:
在这里插入图片描述
​发现:id为肖战,取出来的数据不对,应该是体育的一行。所以,order by 未起到作用,实际上只是group by 抽取了第一行数据;
查了下网上的解决办法,可以通过在order by 后加limit语句的方式来解决。

select a.* from
(select * from test
order by grade desc, grade2 desc limit 1000) a 
group by a.id 

在这里插入图片描述以上方法可行。

方法二:使用row_number函数,对分组排序后的数据增加行索引
SELECT *
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY id ORDER BY grade DESC,grade2 desc) AS row_num
    FROM test
) AS ranked
WHERE row_num = 1;

子查询结果:
在这里插入图片描述
执行结果:
在这里插入图片描述

2、取每个id,两列字段值总和最高的一行记录

WITH RankedScores AS (  -- 定义一个公用表表达式(CTE)名为RankedScores
    SELECT 
        id,  -- 选择id列
        subject1,  -- 选择subject1列
        grade,  -- 选择grade1列
        grade2,  -- 选择grade2列
        (grade + grade2) AS total_grade,  -- 计算grade1和grade2的总和,并将其命名为total_grade
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY (grade + grade2) DESC) AS rn  -- 使用窗口函数ROW_NUMBER()为每个id按照total_grade降序排序生成一个行号rn
    FROM 
        A  -- 从表A中选择数据
)
SELECT 
    id,  -- 选择id列
    subject1,  -- 选择subject1列
    grade1,  -- 选择grade1列
    grade2,  -- 选择grade2列
    total_grade  -- 选择计算得到的total_grade列
FROM 
    RankedScores  -- 从公用表表达式RankedScores中选择数据
WHERE 
    rn = 1;  -- 只选择行号rn为1的行,即每个id中total_grade最高的那一行

3、取每个科目,两次得分均最高的一行记录

SELECT 
    A.*
FROM 
    (
        SELECT 
            A.*,
            ROW_NUMBER() OVER (PARTITION BY subject1 ORDER BY grade1 DESC, grade2 DESC) AS rn
        FROM 
            A
    ) AS RankedScores
WHERE 
    rn = 1;

4、取每个科目,两列字段值总和最高的一行记录

SELECT 
    A.*
FROM 
    (
        SELECT 
            A.*,
            ROW_NUMBER() OVER (PARTITION BY subject1 ORDER BY (grade1 + grade2) DESC) AS rn
        FROM 
            A
    ) AS RankedScores
WHERE 
    rn = 1;

处理方式一样,把按成员分组改成按学科即可,表A中数据,偶尔可能不满足两个字段值均最高的数据(暂不纠结啦),主要考虑实现方式。

注:如计算字段为文本,请先进行字符类型的转换,参考以下代码:

SELECT 
    A.*
FROM 
    (
        SELECT 
            A.*,
            TRY_CONVERT(FLOAT, grade1) AS grade1_numeric,
            TRY_CONVERT(FLOAT, grade2) AS grade2_numeric,
            ROW_NUMBER() OVER (PARTITION BY subject1 ORDER BY (TRY_CONVERT(FLOAT, grade1) + TRY_CONVERT(FLOAT, grade2)) DESC) AS rn
        FROM 
            A
        WHERE 
            TRY_CONVERT(FLOAT, grade1) IS NOT NULL AND 
            TRY_CONVERT(FLOAT, grade2) IS NOT NULL
    ) AS RankedScores
WHERE 
    rn = 1;
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐