关系数据库标准语言SQL

开始学习数据库,以后每天把学习的知识点一点点记录


3.3.1 概述

3.3.2 单表查询

3.3.3 连接查询

3.3.4 嵌套查询

3.3.5 集合查询


3.3.6 小结


  语句格式:


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

                                       [,<目标列表达式>]…

FROM <表名或视图名>[,<表名或视图名>]…

[ WHERE<条件表达式>]

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

[ ORDERBY<列名2>[ ASC|DESC ] ];

语句格式:



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


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


WHERE 子句 :指定查询条件


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


HAVING 短语 :筛选出只有满足指定条件的组


ORDER BY 子句 :对查询结果表按指定列值的升序或降序排序
学生数据库举例:


学生-课程数据库


学生表: Student( Sno , Sname , Ssex , Sage , Sdept )


课程表: Course( Cno , Cname , Cpno , Ccredit )


学生选课表: SC( Sno , Cno , Grade)



 

数据库--学习笔记1_字符串

数据库--学习笔记1_数据库_02

数据库--学习笔记1_字符串_03

查询操作:

3.3.1 概述

1-- 单表查询

3.3.3 连接查询

3.3.4 嵌套查询

3.3.5 集合查询


3.3.6 小结

单表查询:

查询仅涉及一个表,是一种最简单的查询操作:

一、选择表中的若干列

二、选择表中的若干元组

三、对查询结果排序

四、使用集函数

五、对查询结果分组

2--查询指定列:

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

SELECT Sno,Sname    FROM Student;



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

SELECT Sname,Sno,Sdept FROM Student;



3--查询全部列:

[例3] 查询全体学生的详细记录。

SELECT  Sno,Sname,Ssex,Sage,Sdept FROMStudent;
SELECT  * FROMStudent;




4--查询经过计算的值 


SELECT子句的<目标列表达式>为表达式


算术表达式


字符串常量


函数


列别名



[例4] 查全体学生的姓名及其出生年份。

SELECT Sname,2007-Sage FROMStudent;



[例5] 查询全体学生的姓名、出生年份和所有系。在出生年份前面增加一个说明,在系名称后面增加一个“系”作为表示

SELECT Sname,'出生年份:', 2007-Sage,  Sdept +  '系' FROMStudent;
SELECT Sname'姓名','Year of Birth: ' '生日标识', 2007-Sage '生日',  Sdept+'系' '系名' FROM Student;



5--选择表中的若干元组


1.消除取值重复的行


2.查询满足条件的元组


  在 SELECT 子句中使用 DISTINCT 短语


假设SC表中有下列数据 

              Sno      Cno       Grade

              -------    -------    -------

              95001       1        92

              95001       2        85

              95001       3        88

              95002       2        90

              95002       3        80

ALL 与DISTINCT

[例6] 查询选修了课程的学生学号。

(1)SELECT Sno   FROM SC;

(默认ALL)

SELECT ALL Sno FROM SC;

(2) SELECT DISTINCT Sno FROM SC;



 注意 DISTINCT短语的作用范围是所有目标列


例:查询选修课程的各种成绩

错误的写法

SELECTDISTINCT Cno,DISTINCTGrade  FROMSC;


正确的写法

SELECTDISTINCT Cno,Grade    FROM SC;


查询满足条件的元组



WHERE子句常用的查询条件


数据库--学习笔记1_数据库_04


在WHERE子句的<比较条件>中使用比较运算符


  = , > , < , >= , <= , != 或 <> , !> , !< ,


  逻辑运算符 NOT +  比较运算符


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


SELECT Sname, Sage  FROM    Student   WHERE Sage < 20;SELECT Sname,Sage  FROM    Student 
WHERE NOT Sage >= 20

确定范围” :



  使用谓词   BETWEEN …  AND  …


                        NOT BETWEEN  …  AND  …

[例10] 查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。

SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;


[例11] 查询年龄不在20~23岁之间的学生姓名、系别和年龄。

SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23

确定集合


使用谓词     IN<值表>, NOT IN <值表>

          <值表>:用逗号分隔的一组取值

[例12]查询信息系(IS)和计算机科学系(CS)学生的姓名和性别。

SELECT Sname, Ssex
FROM Student
WHERE Sdept IN ( 'IS', 'CS' );


[例13]查询既不是信息系又不是计算

           机科学系的学生的姓名和性别。

SELECT Sname,Ssex
FROM Student
WHERE Sdept NOT IN ( 'IS''CS' );
<span style="color:#FF0000;">
</span>

字符串匹配:


n [NOT]LIKE  ‘ < 匹配串 > ’  [ESCAPE ‘ < 换码字符 > ’ ]


<匹配串>:指定匹配模板

      匹配模板:固定字符串或含通配符的字符串

      当匹配模板为固定字符串时,

      可以用 = 运算符取代LIKE谓词

      用 != 或<>运算符取代NOTLIKE谓词

  通配符:



w % ( 百分号 )  代表任意长度(长度可以为 0 )的字符串


  例: a%b 表示以 a 开头,以 b 结尾的任意长度的字符串。如 acb , addgb , ab 等都满足该匹配串


² _ ( 下横线 )  代表任意单个字符


  例: a_b 表示以 a 开头,以 b 结尾的长度为 3 的任意字符串。如 acb , afb 等都满足该匹配串


 
ESCAPE 短语:
当用户要查询的字符串本身就含有 % 或 _ 时,要使用 ESCAPE'< 换码字符 >' 短语对通配符进行转义。


1) 匹配模板为固定字符串

[例14] 查询学号为95001的学生的详细情况。

 

SELECT*   
FROM Student
WHERE SnoLIKE '95001';



等价于:

SELECT  *
FROM Student
WHERE Sno= '95001'


[例15] 查询所有姓刘学生的姓名、学号和性别。

SELECT Sname,Sno,Ssex
FROM Student
WHERE SnameLIKE ‘刘%’;

[例16] 查询姓“刘"且全名为三个汉字的学生的姓名。

SELECT Sname
FROM Student
WHERE Sname LIKE ‘刘__';

这里有一个疑问?:



今天数据库实验,关于查询姓“李”的姓名后面到底写多少个下划线,回去试验了一下

当下划线为一的时候:


数据库--学习笔记1_数据库_05



当下划线为二的时候:


数据库--学习笔记1_下划线_06


可以看出当下划线为二的时候,数据库会将下划线只有一行的姓名 同时检索出来。同理,如果选择为三的时候,会出现:


数据库--学习笔记1_字符串_07

的结果,也就是说会一起把前面的所有信息检索出来,


但如何只想检索只有两个下划线的姓名呢,也很简单,加一条语句: 


数据库--学习笔记1_下划线_08

还有一种方法?:


select * 
from student
where sname like '刘%' and len(sname)=2

但是:

如果之前我定义的范围最多可以打五个下划线,
但是出来的结果却只有



数据库--学习笔记1_数据库_09

,初学数据库,有一个疑问,希望有明白的给点解释,THs.




ok,继续:


匹配模板为含通配符的字符串

[例17] 查询名字中第2个字为“伟”字的学生的姓名和学号。


<pre name="code" class="sql">SELECT FRIST.Cno '课程名',SECOND.Cpno '先修课程'
FROM Course FRIST,Course SECONDWHERE FRIST.Cpno=SECOND.Cno


SELECT Sname,Sno FROM Student WHERE Sname LIKE ‘_伟%';



[例18] 查询所有不姓刘的学生姓名。

SELECTSname,Sno,Ssex
FROM Student
WHERE SnameNOT LIKE '刘%'

使用换码字符将通配符转义为普通字符

  [例19] 查询课程名称中包含“面向对象_C++课程”的课程号和学分。

SELECT Cno, Ccredit
FROM Course
WHERE Cname LIKE%面向对象\_C++%’ ESCAPE ‘\’

使用换码字符将通配符转义为普通字符(续)

[例20] 查询以"DB_"开头,且倒数第3个字符为i的课程的详细情况。     

SELECT  *
FROM Course
WHERE Cname LIKE 'DB\_%i_ _' ESCAPE ' \ '


使用谓词 ISNULL 或 ISNOT NULL


“ ISNULL ” 不能用 “ =NULL ” 代替


[例21]查询每一课程的间接先修课,以“课程名”、“先修课名”作列名。


SELECT FRIST.Cno '课程名',SECOND.Cpno '先修课程'
FROM Course FRIST,Course SECONDWHERE FRIST.Cpno=SECOND.Cno

用逻辑运算符 AND 和 OR 来联结多个查询条件

AND 的优先级高于 OR


可以用括号改变优先级


可用来实现多种其他谓词


[NOT]IN


[NOT] BETWEEN …   AND  …

[例23] 查询计算机系年龄在20岁以下的学生姓名。

SELECT Sname
FROM Student
WHERE Sdept= 'CS' AND Sage<20;


[例24] 查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。


SELECTSname,Ssex
FROMStudent
WHERESdeptIN ( 'IS', 'MA', 'CS' )


可改写为:


SELECTSname,Ssex
FROM Student
WHERE Sdept='IS' OR Sdept='MA' OR Sdept='CS ';

[ 例 25]  查询年龄在 20~23 岁(包括 20 岁和 23 岁)之间的学生的姓名、系别和年龄 。


SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23
可改写为:
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage>=20 AND Sage<=23

对查询结果排序

使用ORDERBY子句



可以按一个或多个属性列排序



升序: ASC ;降序: DESC ;缺省值为升序



当排序列含空值时

NULL  作为最小值


对查询结果排序(续)

[例24] 查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列


<span style="color:#000000;">SELECT Sno,Grade
FROM SC
WHERE Cno= '3'
ORDER BY Grade DESC;
</span>

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

<span style="color:#000000;">SELECT  *
FROM Student
ORDER BY Sdept, Sage DESC;
</span>


使用集函数



5类主要集函数
计数
COUNT[DISTINCT|ALL] *
COUNT[DISTINCT|ALL] <列名>
计算总和
SUM([DISTINCT|ALL] <列名>
计算平均值
AVG([DISTINCT|ALL] <列名>


求最大值
MAX([DISTINCT|ALL] <列名>
求最小值
MIN([DISTINCT|ALL] <列名>
DISTINCT短语:在计算时要取消指定列中的重复值
ALL短语:不取消重复值
ALL为缺省值


[例26] 查询学生总人数。

SELECT COUNT(*)
FROM Student;


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

SELECT COUNT(DISTINCT Sno)
FROM SC;
注:用DISTINCT以避免重复计算学生人数


[例28] 计算2号课程的学生平均成绩。

SELECT AVG(Grade)
FROM SC
WHERE Cno= ' 2 '


[例29] 查询选修3号课程的学生最高分数。

SELECT MAX(Grade)
FROM SC
WHER Cno= ' 3'


对查询结果分组


使用GROUPBY子句分组 

细化集函数的作用对象


未对查询结果分组,集函数将作用于整个查询结果


对查询结果分组后,集函数将分别作用于每个组

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

SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;


对查询结果分组


GROUPBY 子句的作用对象是查询的中间结果表



分组方法:按指定的一列或多列值分组,值相等的为一组



使用 GROUPBY 子句后, SELECT 子句的列名列表中只能出现分组属性和集函数





先写到这吧,,下次更新。。