• sql 用Group by分组后,取每组的前几条记录


    转自:http://www.cnblogs.com/wangpei/p/6600584.html

    --查询每门课程的前2名成绩
    CREATE TABLE StudentGrade(
    stuId CHAR(4),    --学号
    subId INT,        --课程号
    grade INT,        --成绩
    PRIMARY KEY (stuId,subId)
    )
    GO
    --表中数据如下
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('001',1,97);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('001',2,50);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('001',3,70);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('002',1,92);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('002',2,80);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('002',3,30);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('003',1,93);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('003',2,95);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('003',3,85);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('004',1,73);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('004',2,78);
    INSERT INTO StudentGrade(stuId,subId,grade) VALUES('004',3,87);
    GO
    /*
    要查询每门课程的前2名成绩
    001 1 97
    003 1 93
    003 2 95
    002 2 80
    004 3 87
    003 3 85
    如何实现?
    */
    --查看数据
    select * from StudentGrade
     
     
    --假如出现并列时,也只取两个同学的话。
    --方法一:
    select distinct *
    from studentgrade as t1
    where stuid in
    (select top 2 stuid
     from studentgrade as t2
     where t1.subid=t2.subid
             order by t2.grade desc)
    order by subid, grade desc
     
    --方法二:
    select * from StudentGrade a where (select count(1) from studentGrade where subId=a.subId and grade>=a.grade)<=2
     
    --方法三:
    select * from StudentGrade t
    where (select count(1) from StudentGrade where subid=t.subid and grade>t.grade)<=1
    order by subId,grade desc
     
    --结果
    /*
    stuId subId       grade      
    ----- ----------- -----------
    001   1           97
    003   1           93
    003   2           95
    002   2           80
    004   3           87
    003   3           85
     
    (6 row(s) affected)
    */
     
    共有三种方案,从难易程度上讲我倾向于后两种,从查询逻辑思想上来讲后两种是一样的
     
    select * from StudentGrade t
    where (select count(1) from StudentGrade where subid=t.subid and grade>t.grade)<=1
    order by subId,grade desc
     
    我是这样理解的,看成两张表A和B,条件为A表的学科=B表的学科,select count(1) from StudentGrade where subid=t.subid and grade>t.grade,返回A表的学科=B表的学科并且A表的成绩小于B表的成绩的影响行数,如果所影响的行数为零说明它的成绩是最高的,如果等于1的话就是最高的两个成绩。这就是查询条件,再按 subId,grade 排序。这种查询思想很值得我学习
  • 相关阅读:
    Ubuntu 16.04实现SSH无密码登录/免密登录/自动登录(ssh-keygen/ssh-copy-id)
    简单理解Linux的Loopback接口
    iptables为什么需要增加loopback回环的规则
    [ASP.NET Core 3框架揭秘] 依赖注入[10]:与第三方依赖注入框架的适配
    [ASP.NET Core 3框架揭秘] 依赖注入[9]:实现概述
    [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期
    [ASP.NET Core 3框架揭秘] 依赖注入[7]:服务消费
    [ASP.NET Core 3框架揭秘] 依赖注入[6]:服务注册
    [ASP.NET Core 3框架揭秘] 依赖注入[5]: 利用容器提供服务
    AOP框架Dora.Interception 3.0 [5]: 基于策略的拦截器注册方式
  • 原文地址:https://www.cnblogs.com/jt925/p/10746195.html
Copyright © 2020-2023  润新知