zoukankan      html  css  js  c++  java
  • T-sql GroupBy语句常见问题处理

    1.问题描述

    现在有一张course表(含课程编号和名称)和一张sc表(含学生学号,选修课程的编号以及考试成绩),如下:

    现在想要查询所有课程编号、对应的课程名称以及选修该课程的所有学生的平均成绩。
    一开始我的想法就是用以下的查询语句:

    select sc.cno as 课程编号, cname as 课程名称, Avg(grade) as 平均成绩
    from course, sc
    where course.cno = sc.cno
    group by sc.cno

    但是显然会报错:

    于是开始想其他的办法。

    2.第一种方法

    首先想到的当然是按照报错信息来了,既然cname不在GROUP BY子句中,那就放到GROUP BY子句中呗,如下:

    select sc.cno as 课程编号, cname as 课程名称, Avg(grade) as 平均成绩
    from course, sc
    where course.cno = sc.cno
    group by sc.cno, cname


    但是这种方法是不严谨的,因为这里是知道每个课程号只对应一个课程名称,所以这种办法才行。但是在其他的情况中,一旦每个课程号不是只对应一个课程名称,那就很乱了。所以还得想其他办法。

    3.第二种方法

    第二个想到的方法也是按照报错信息来,将cname变成聚合函数就行了,如下:

    select sc.cno as 课程编号, Max(cname) as 课程名称, Avg(grade) as 平均成绩
    from course, sc
    where course.cno = sc.cno
    group by sc.cno
    -- 或者
    select sc.cno as 课程编号, Min(cname) as 课程名称, Avg(grade) as 平均成绩
    from course, sc
    where course.cno = sc.cno
    group by sc.cno


    但是这种方法是比第一种方法还不如的。因为课程名称是字符串,取最大最小值毫无意义。

    4.第三种方法

    接下来就是正确的方法了,也就是标题提到的扩展SQL语句,也算是嵌套SQL语句。
    因为select...from...中,from后面接的是,所以这个表可以是另一个select语句查询出来的结果,如下:

    select course.cno as 课程编号, cname as 课程名称, tmp.平均成绩
    from course, (select cno, Avg(grade) as 平均成绩 from sc group by cno) as tmp
    where course.cno = tmp.cno


    在select...from...中的from后面嵌套一个select...from...,并且将嵌套的select...from...查询出来的表起个别名tmp,这样就能用tmp来操作这张表了。

    5.第四种方法

    既然select...from...中的from后面可以嵌套一个表,那么select...from...中的select后面可以嵌套一个列吗?
    答案是可以的。如下:

    select cno as 课程编号,
           (select cname from course where sc.cno=course.cno) as 课程名称,
           Avg(grade) as 平均成绩
    from sc
    group by sc.cno


    要注意的是在(select cname from course where sc.cno=course.cno)中必须要有where sc.cno=course.cno,只有这样查询出来的结果才是一一对应的,否则查询出来的结果是很多的,然后每个cno会对应很多个cname,这样就会乱套,并且这样是会报错的。

  • 相关阅读:
    【C#】:浅谈反射机制 【转】
    ArcGIS Server 10中的切图/缓存机制深入【转】
    ArcGIS Server的切图原理深入【转】
    【OpenGL】用OpenGL shader实现将YUV(YUV420,YV12)转RGB-(直接调用GPU实现,纯硬件方式,效率高)
    MFC 带Ribbonbar的窗口 实现全屏和取消全屏
    C#.net开发 List与DataTable相互转换 【转】
    Net编程 详解DataTable用法【转】
    三维空间两直线/线段最短距离、线段计算算法 【转】
    OSG立体模式下动态修改相机远近裁剪面的实现
    用curl去探测接口是否正常返回结果,若没有正常返回则触发报警
  • 原文地址:https://www.cnblogs.com/l1pe1/p/7783349.html
Copyright © 2011-2022 走看看