数据库系统概论5版第三章关系数据库标准语言SQL【中】——数据查询(select)

目录

(一)、查询语句格式       

(二)、单表查询

(三)、连接查询

(四)、嵌套查询

(五)、集合查询

(六)、基于派生表的查询


三、数据查询(select)

(一)、查询语句格式       

SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>] … 

//目标列表达式可以是表中的属性列、表达式、字符串常量、函数

       FROM <表名或视图名>[,<表名或视图名> ]…|(SELECT 语句)     

                   [AS]<别名>

[ WHERE <条件表达式> ]

[ GROUP BY <列名1> [ HAVING <条件表达式> ] ]

[ ORDER BY <列名2> [ ASC|DESC ] ];

理解语句:整个select语句的含义是,根据where子句的条件表达式从from子句指定的基本表、视图、派生表中找出满足条件的元组,再按select子句中的目标列表达式选出元组中的属性值形成结果表。

SELECT子句:指定要显示的属性列

FROM子句:指定查询对象(基本表或视图)

WHERE子句:指定查询条件

GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。

HAVING短语:只有满足指定条件的组才予以输出

ORDER BY子句:对查询结果表按指定列值的升序或降序排序

(二)、单表查询

1、查询范围:查询仅涉及一个表

2、选择表中的若干列

查询指定列:

[3.16]  查询全体学生的学号与姓名。

  SELECT Sno,Sname

  FROM Student; 

[3.17]  查询全体学生的姓名、学号、所在系。

  SELECT Sname,Sno,Sdept

  FROM Student;

查询全部列:

选出所有属性列的两种方法:

  • 在SELECT关键字后面列出所有列名
  • 将<目标列表达式>指定为  *

[3.18]  查询全体学生的详细记录

SELECT  Sno,Sname,Ssex,Sage,Sdept

FROM Student;

SELECT  *

FROM Student;

查询经过计算的值:

[3.20]

SELECT Sname,'Year of Birth: ',2014-Sage,LOWER(Sdept)

FROM Student;

使用列别名改变查询结果的列标题:

SELECT Sname NAME,'Year of Birth:'  BIRTH,

2014-Sage  BIRTHDAY,LOWER(Sdept)  DEPARTMENT

 FROM Student;

3、选择表中的若干元组

消除取值重复的行:使用distinct消除重复

指定DISTINCT关键词,去掉表中重复的行

   SELECT DISTINCT Sno

    FROM SC;

查询满足条件的元组:使用where子句实现

[3.23]查询所有年龄在20岁以下的学生姓名及其年龄。

     SELECT Sname,Sage

     FROM     Student   

     WHERE  Sage < 20;

WHERE   Sage BETWEEN 20 AND 23;

WHERE Sdept IN ('CS','MA’,'IS' );

WHERE  Sno LIKE ‘201215121';

WHERE  Sname LIKE '刘%';

//百分号%代表任意长度的字符串

WHERE  Sname LIKE '欧阳__';

//下横线代表任意单个字符

WHERE  Grade IS NULL

WHERE Sdept= 'CS' AND Sage<20;

4、ORDER BY子句

作用:用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序ASC、降序DESC排列,默认为升序。

[3.40]查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。

        SELECT  *

        FROM  Student

        ORDER BY Sdept, Sage DESC; 

5、聚集函数

作用:为了进一步方便用户,增强检索功能,提供了SQL聚集函数。

统计元组个数

     COUNT(*)

统计一列中值的个数

     COUNT([DISTINCT|ALL] <列名>)

计算一列值的总和(此列必须为数值型)

SUM([DISTINCT|ALL] <列名>) 

计算一列值的平均值(此列必须为数值型)

AVG([DISTINCT|ALL] <列名>)

求一列中的最大值和最小值

   MAX([DISTINCT|ALL] <列名>)

   MIN([DISTINCT|ALL] <列名>)

例题:

    [3.41]  查询学生总人数。

    SELECT COUNT(*)

    FROM  Student; 

     [3.42]  查询选修了课程的学生人数。

     SELECT COUNT(DISTINCT Sno)

     FROM SC;

     [3.43]  计算1号课程的学生平均成绩。

       SELECT AVG(Grade)

FROM    SC

       WHERE Cno= ' 1 '

5.GROUP BY子句

作用:GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组;如:选课人数相同的学生为一组,就可以统计选课数相同的学生人数了。

[3.46]  求各个课程号及相应的选课人数。

     SELECT Cno,COUNT(Sno)

     FROM    SC

     GROUP BY Cno; 

     查询结果为:

 

注意:WHERE子句中是不能用聚集函数作为条件表达式,只能使用HAVING子句。

   错误: WHERE AVG(Grade)>=90  !!!

   正确: HAVING AVG(Grade)>=90  !!!

HAVING短语与WHERE子句的区别:

  • 作用对象不同
  • WHERE子句作用于基表或视图,从中选择满足条件的元组
  • HAVING短语作用于组,从中选择满足条件的组。

(三)、连接查询

连接查询是针对多个表进行的,是关系数据库中最主要的查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询、复合条件连接查询。

连接查询的where子句中用来连接两个表的条件称为连接条件或连接谓词,一般格式为: 

  WHERE   [<表名1>.]<列名1>  <比较运算符>  [<表名2>.]<列名2>

1、等值连接与非等值连接、自然连接

等值连接:比较运算符为 =

例如:

WHERE  Student.Sno = SC.Sno;

WHERE    [<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>

自然连接:在等值连接中把重复的属性列去掉则为自然连接。

2、自身连接

自身连接:一个表与其自己进行连接,需要给表起别名以示区别

由于所有属性名都是同名属性,因此必须使用别名前缀

[3.52]查询每一门课的间接先修课(即先修课的先修课)

    SELECT  FIRST.Cno, SECOND.Cpno

//  为要查询的表Course起两个名字别名:FIRST、SECOND

     FROM  Course  FIRST, Course  SECOND

     WHERE FIRST.Cpno = SECOND.Cno;

3、外连接

外连接与普通连接的区别:

普通连接操作只输出满足连接条件的元组

外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出

左外连接:列出左边关系中所有的元组

右外连接:列出右边关系中所有的元组

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade

    FROM  Student  LEFT OUT JOIN SC ON   

                 (Student.Sno=SC.Sno);

4、多表连接

多表连接:两个以上的表进行连接

[3.54]查询每个学生的学号、姓名、选修的课程名及成绩

  SELECT Student.Sno, Sname, Cname, Grade

   FROM    Student, SC, Course    /*多表连接*/

   WHERE Student.Sno = SC.Sno  AND  SC.Cno = Course.Cno;

(四)、嵌套查询

嵌套查询概述:

一个SELECT-FROM-WHERE语句称为一个查询块

将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询

例如:

     SELECT Sname          /*外层查询/父查询*/

     FROM Student

     WHERE Sno IN

                        ( SELECT Sno    /*内层查询/子查询*/

                          FROM SC

                          WHERE Cno= ' 2 ');

 

子查询的限制:不能使用ORDER BY子句

1、带有IN谓词的子查询

[3.56]查询选修了课程名为“信息系统”的学生学号和姓名

   SELECT Sno,Sname    最后在Student关系中

    FROM    Student          取出SnoSname

   WHERE Sno  IN

        (SELECT Sno       然后在SC关系中找出选

         FROM    SC         修了3号课程的学生学号

         WHERE  Cno IN

               (SELECT Cno     首先在Course关系中找出

                 FROM Course   信息系统”的课程号,为3

                  WHERE Cname= '信息系统'                     

            )  );

2、带有比较运算符的子查询

当能确切知道内层查询返回单值时,可用比较运算符(><=>=<=!=< >)。

= 代替IN

     SELECT Sno,Sname,Sdept

     FROM    Student

     WHERE Sdept   =

                   (SELECT Sdept

                    FROM    Student

                    WHERE Sname= '刘晨');

3、带有ANY(SOME)或ALL谓词的子查询

使用ANYALL谓词时必须同时使用比较运算

语义为:

> ANY  大于子查询结果中的某个值      

> ALL  大于子查询结果中的所有值

< ANY  小于子查询结果中的某个值   

< ALL  小于子查询结果中的所有值

>= ANY  大于等于子查询结果中的某个值   

>= ALL  大于等于子查询结果中的所有值

[3.58]  查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄

    SELECT Sname,Sage

    FROM    Student

    WHERE Sage < ANY

(SELECT  Sage

 FROM    Student

WHERE Sdept= ' CS ')

     AND Sdept <> ‘CS ' ;           /*父查询块中的条件 */

4、带有EXISTS谓词的子查询

带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”

若内层查询结果非空,则外层的WHERE子句返回真值

若内层查询结果为空,则外层的WHERE子句返回假值

(五)、集合查询

集合操作的种类:并操作UNION—或、交操作INTERSECT—与、差操作EXCEPT

[3.64]  查询计算机科学系的学生及年龄不大于19岁的学生。

        SELECT *

        FROM Student

        WHERE Sdept= 'CS'

        UNION

        SELECT *

        FROM Student

        WHERE Sage<=19;

UNION:将多个查询结果合并起来时,系统自动去掉重复元组

UNION ALL:将多个查询结果合并起来时,保留重复元组

(六)、基于派生表的查询

子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这时子查询生成的临时派生表(Derived Table)成为主查询的查询对象

[3.57]找出每个学生超过他自己选修课程平均成绩的课程号

    SELECT Sno, Cno

    FROM SC, (SELECTSno, Avg(Grade)

                        FROM SC

                GROUP BY Sno)

 AS   Avg_sc(avg_sno,avg_grade) //派生表

    WHERE SC.Sno = Avg_sc.avg_sno

      and SC.Grade >=Avg_sc.avg_grade

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值