有一个学生表,里面有 学号 功课编号
学生成绩三个字段.用一个SQL查询语句得出每门功课成绩最好的前两名学号  功课编号     学生成绩
 1          1             99
 2          1             98
 3          1             100
 4          2             88
 5          2             87
 6          2             88
 7          3             99
 8          3             88
 9          3             100
SELECT 学生表1.* 
FROM 学生表 学生表1 WHERE 学生表1.学号 IN 
(SELECT TOP 2 学生表.学号 
FROM 学生表 
WHERE 学生表.功课编号 = 学生表1.功课编号 
ORDER BY 学生成绩 DESC)
我就是想不明白,为什么要用自连接,学生表.功课编号 = 学生表1.功课编号,本来不就是相等么??

解决方案 »

  1.   

    这不是oracle吧。oracle没top这个函数。像这种自连接效率不高,oracle中用分析函数处理这类SQL查询很方便。
      

  2.   

    SQLSERVER 中有top。oracle没有的。
      

  3.   

    select *
    from (
    SELECT 学生表1.* 
    FROM 学生表 学生表1
    order by  学生成绩 DESC)
     where rownum<=2oracle 的写法
      

  4.   

    为了查询
    SELECT TOP 2 学生表.学号 
    FROM 学生表 
    WHERE 学生表.功课编号 = 学生表1.功课编号 
    ORDER BY 学生成绩 DESC
      

  5.   

    要有并列的,就需要用dense_rank这个分析函数了
      

  6.   

    dense_rank
    這個函數怎樣寫??
      

  7.   

    dense_rank() over(partition by  ... order by ....)
      

  8.   


    create table t (cn integer,kn integer,score number)
    insert into t values(1,1,99);
    insert into t values(2,1,98);
    insert into t values(3,1,100);
    insert into t values(4,2,88);
    insert into t values(5,2,87);
    insert into t values(6,2,88);
    insert into t values(7,3,99);
    insert into t values(8,3,88);
    insert into t values(9,3,100);
    select * from t;
    select *
      from (select cn,
                   kn,
                   score,
                   dense_rank() over(partition by kn order by score desc) num
              from t)
     where num <= 2;
    --查询结果:
        CN KN SCORE NUM
    1 3 1 100 1
    2 1 1 99 2
    3 4 2 88 1
    4 6 2 88 1
    5 5 2 87 2
    6 9 3 100 1
    7 7 3 99 2
      

  9.   

    楼上的不错的.
    另wren4255 注意:
    要的前两名中如果有分数一样,怎样取.
    一种是用dense_rank() 如上例子中取两名时实际是三个人,另一种可以用Rank.select *
    from (select cn,
                   kn,
                   score,
                   rank() over(partition by kn order by score desc) num
              from t)
     where num <= 2;
    --结果-------------------
    SEQ     CN      KN      Score   Num
    1 3 1 100 1
    2 1 1 99 2
    3 4 2 88 1
    4 6 2 88 1
    5 9 3 100 1
    6 7 3 99 2