T stu | sub | score 
            取出学生最高的成绩
                  --->sub | MaxScore 
我写的:
 select sub,Max(score) MaxScore  from T group by sub
                         取出带学生姓名的最高成绩
                                     --->stu | sub | MaxScore
我写的:
select stu,sub,Max(score) MaxScore  from T group by sub,stu --后来发现这个不对 记录多了改后:
select stu,sub,Max(score) MaxScore  from T group by sub
原以为这句不能通过,因为ANSI标准有这个基础定义啊 “所有非聚合列都必须包含在GROUP BY列表中”惊奇!在Mysql里居然能执行。而且返回来想要的结果集。哪位朋友能帮忙在SqlServer或者Oracle上试一下啊 我现在在家,没有SqlServer/Oracle环境

解决方案 »

  1.   

    select stu,sub,Max(score) MaxScore  from T group by sub 
    应该通不过~~
      

  2.   


    --按某一字段分组取最大(小)值所在行的数据
    --(爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-10-23于浙江杭州)
    /*
    数据如下:
    name val memo
    a    2   a2(a的第二个值)
    a    1   a1--a的第一个值
    a    3   a3:a的第三个值
    b    1   b1--b的第一个值
    b    3   b3:b的第三个值
    b    2   b2b2b2b2
    b    4   b4b4
    b    5   b5b5b5b5b5
    */
    --创建表并插入数据:
    create table tb(name varchar(10),val int,memo varchar(20))
    insert into tb values('a',    2,   'a2(a的第二个值)')
    insert into tb values('a',    1,   'a1--a的第一个值')
    insert into tb values('a',    3,   'a3:a的第三个值')
    insert into tb values('b',    1,   'b1--b的第一个值')
    insert into tb values('b',    3,   'b3:b的第三个值')
    insert into tb values('b',    2,   'b2b2b2b2')
    insert into tb values('b',    4,   'b4b4')
    insert into tb values('b',    5,   'b5b5b5b5b5')
    go--一、按name分组取val最大的值所在行的数据。
    --方法1:
    select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
    --方法2:
    select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
    --方法3:
    select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
    --方法4:
    select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
    --方法5
    select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
    /*
    name       val         memo                 
    ---------- ----------- -------------------- 
    a          3           a3:a的第三个值
    b          5           b5b5b5b5b5
    */--二、按name分组取val最小的值所在行的数据。
    --方法1:
    select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
    --方法2:
    select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
    --方法3:
    select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
    --方法4:
    select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
    --方法5
    select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
    /*
    name       val         memo                 
    ---------- ----------- -------------------- 
    a          1           a1--a的第一个值
    b          1           b1--b的第一个值
    */--三、按name分组取第一次出现的行所在的数据。
    select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
    /*
    name       val         memo                 
    ---------- ----------- -------------------- 
    a          2           a2(a的第二个值)
    b          1           b1--b的第一个值
    */--四、按name分组随机取一条数据。
    select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
    /*
    name       val         memo                 
    ---------- ----------- -------------------- 
    a          1           a1--a的第一个值
    b          5           b5b5b5b5b5
    */--五、按name分组取最小的两个(N个)val
    select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
    select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
    select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name,a.val
    /*
    name       val         memo                 
    ---------- ----------- -------------------- 
    a          1           a1--a的第一个值
    a          2           a2(a的第二个值)
    b          1           b1--b的第一个值
    b          2           b2b2b2b2
    */--六、按name分组取最大的两个(N个)val
    select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
    select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
    select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name , a.val
    /*
    name       val         memo                 
    ---------- ----------- -------------------- 
    a          2           a2(a的第二个值)
    a          3           a3:a的第三个值
    b          4           b4b4
    b          5           b5b5b5b5b5
    */
    --七,如果整行数据有重复,所有的列都相同。
    /*
    数据如下:
    name val memo
    a    2   a2(a的第二个值)
    a    1   a1--a的第一个值
    a    1   a1--a的第一个值
    a    3   a3:a的第三个值
    a    3   a3:a的第三个值
    b    1   b1--b的第一个值
    b    3   b3:b的第三个值
    b    2   b2b2b2b2
    b    4   b4b4
    b    5   b5b5b5b5b5
    */
    --在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。
    --创建表并插入数据:
    create table tb(name varchar(10),val int,memo varchar(20))
    insert into tb values('a',    2,   'a2(a的第二个值)')
    insert into tb values('a',    1,   'a1--a的第一个值')
    insert into tb values('a',    1,   'a1--a的第一个值')
    insert into tb values('a',    3,   'a3:a的第三个值')
    insert into tb values('a',    3,   'a3:a的第三个值')
    insert into tb values('b',    1,   'b1--b的第一个值')
    insert into tb values('b',    3,   'b3:b的第三个值')
    insert into tb values('b',    2,   'b2b2b2b2')
    insert into tb values('b',    4,   'b4b4')
    insert into tb values('b',    5,   'b5b5b5b5b5')
    goselect * , px = identity(int,1,1) into tmp from tbselect m.name,m.val,m.memo from
    (
      select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
    ) m where px = (select min(px) from
    (
      select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
    ) n where n.name = m.name)drop table tb,tmp/*
    name       val         memo
    ---------- ----------- --------------------
    a          1           a1--a的第一个值
    b          1           b1--b的第一个值(2 行受影响)
    */
    --在sql server 2005中可以使用row_number函数,不需要使用临时表。
    --创建表并插入数据:
    create table tb(name varchar(10),val int,memo varchar(20))
    insert into tb values('a',    2,   'a2(a的第二个值)')
    insert into tb values('a',    1,   'a1--a的第一个值')
    insert into tb values('a',    1,   'a1--a的第一个值')
    insert into tb values('a',    3,   'a3:a的第三个值')
    insert into tb values('a',    3,   'a3:a的第三个值')
    insert into tb values('b',    1,   'b1--b的第一个值')
    insert into tb values('b',    3,   'b3:b的第三个值')
    insert into tb values('b',    2,   'b2b2b2b2')
    insert into tb values('b',    4,   'b4b4')
    insert into tb values('b',    5,   'b5b5b5b5b5')
    goselect m.name,m.val,m.memo from
    (
      select * , px = row_number() over(order by name , val) from tb
    ) m where px = (select min(px) from
    (
      select * , px = row_number() over(order by name , val) from tb
    ) n where n.name = m.name)drop table tb/*
    name       val         memo
    ---------- ----------- --------------------
    a          1           a1--a的第一个值
    b          1           b1--b的第一个值(2 行受影响)
    */
      

  3.   

    select stu,sub,Max(score) MaxScore  from T group by sub
    Microsoft SQL Server 通不过。
      

  4.   

    sqlserver里通不过。

    http://topic.csdn.net/u/20080726/23/45568f53-069f-472e-80b0-1361a72109de.html
    第7条。mysql里通过,可能是因为人为做了一些预设。
    比如:
    遇到这种情况时,它可能内置了按另一个规则去取非group by 列里的其它列值。相比之下,我并不看好它,更希望看到mssql这样,把人的意想中的跟实际逻辑运行上的区别出来,让人意识到逻辑问题。
      

  5.   

    select a.stu , a.sub , a.score from tb a where (select COUNT(*) from tb b where b.score > a.score and a.sub =b.sub ) =0 这个试试 
      

  6.   

    说要一句SQL写出来 真的没想出来
      

  7.   

    这样行么?select stu from T,(select sub,Max(score) MaxScore  from T group by sub) t  where T.sub=t .sub and T.score=t.score
      

  8.   

    哦 少东西了 select T.stu,T.sub,t.MaxScore from T,(select sub,Max(score) MaxScore  from T group by sub) t  where T.sub=t .sub and T.score=t.score 
      

  9.   


    select a.stu,b.sub,b.scorefrom T a,(select sub,max(score) as score from T group by sub) bwhere a.score=b.score and a.sub=b.sub 
    T  stu | sub | score 我是在mssql中运行的
      

  10.   

    如4楼所言,该SQL语句在MS SQL Server中是行不通的。
    在MS SQL Server中的写法,11楼与12楼已经给出了答案,两者思路完全一致。——而且我觉得这是最好的写法了。当然,如果想不使用GROUP BY子句,也是可以的,可以使用相关子查询来实现:select stu, sub, score from T t
    where score in
    (select top 1 score from T where sub = t.sub order by score desc)
    order by sub, score desc -- 此行代码(排序子句)仅仅是为了增强结果集的可读性,可省此思路相对于GROUP BY的优点在于,不但可以查每门科目最高(或最低)的分数,而且想查前几名都可以。呵呵。
    比如另一道类似的面试题:查每门科目的前两名
    只需要将之前的语句改一处即可,如下:select stu, sub, score from T t
    where score in
    (select top 2 score from T where sub = t.sub order by score desc)
      

  11.   

    MYSQL里能通过,不一定在SQL里能通过。毕竟每种数据库都有自己的SQL定义和特性,只是都是在ANSI_SQL的框架下而已。