数据查询一般格式为:
SELECT [ALL|DISTINCT]<目标列表达式>[,<目标列表达式>]···
FROM<表名或视图名>[,<表名或视图名>···]|(<SELECT语句>)[AS]<别名>
[WHERE<条件表达式>]
[GROUP BY<列名1>[HAVING<条件表达式>]]
[ORDER BY<列名2>[ASC |DESC]];
整个SELECT语句的含义是,根据WHERE子句的条件表达式从FROM子句指定的基本表、视图或派生表中找出满足条件的元组,再按SELECT子句中的目标列表达式选出元组中的属性值形成结果表。
如果有GROUP BY 子句,则将结果按<列名1>的值进行分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。如果GROUP BY子句带HAVING短语,则只有满足指定条件的组才予以输出。
如果有ORDER BY子句,则结果表还要按照<列名2>的值的升序或降序排序。
Use school1
GO
SELECT Sname,Sno,Sdept
FROM Student

Use school1
GO
SELECT *
FROM Student

Use school1
GO
SELECT Sname,2014-Sage /* 查询结果的第二列是一个算数表达式*/
FROM Student

Use school1
GO
SELECT Sname,'Year of Birth',2014-Sage,LOWER(Sdept)
FROM Student

可以通过指定别名来改变查询结果的列标题
Use school1
GO
SELECT Sname,'Year of Birth',2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT
FROM Student

消除重复的行
Use school1
GO
SELECT Sno
FROM SC

查询结果中包含了许多重复的行。我们可以指定DISTINCT来去掉表中的重复行。
Use school1
GO
SELECT DISTINCT Sno
FROM SC

| 查询条件 | 谓词 |
|---|---|
| 比较 | =,>,<,>=,<=,!=,<>,!>,!<;NOT+上述比较运算符 |
| 确定范围 | BETWEEN AND,NOT BETWEEN AND |
| 确定集合 | IN,NOT IN |
| 字符匹配 | LIKE,NOT LIKE |
| 空值 | IS NOLL,IS NOT NULL |
| 多重条件(逻辑运算) | AND,OR,NOT |
Use school1
GO
SELECT Sname,Sage
FROM Student
WHERE Sage<20;

Use school1
GO
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;

谓词IN可以用来查找属性值属于指定集合的元组。
查找计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名和性别。
Use school1
GO
SELECT Sname,Ssex
FROM Student
WHERE Sdept IN ('计算机','数学','信息');

谓词LIKE可以用来进行字符串的匹配。
Use school1
GO
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname LIKE '刘%'

Use school1
GO
SELECT Sname
FROM Student
WHERE Sname LIKE '范__';

Use school1
GO
SELECT Sname
FROM Student
WHERE Sname LIKE '_林%';

某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
Use school1
GO
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL;
注意,这里的IS不能用等号代替。
用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序。
Use school1
GO
SELECT *
FROM Student
ORDER BY Sdept,Sage DESC;

| COUNT(*) | 统计元组个数 |
|---|---|
| COUNT([DISTINCT ALL])<列名> | 统计一列中值的个数 |
| SUM | 计算一列值的总和(此列必须是数值型) |
| AVG | 计算一列值的平均值(此列必须是数值型) |
| MAX | 求一列值中的最大值 |
| MIN | 求一列值中的最小值 |
Use school1
GO
SELECT COUNT(*)
FROM Student

Use school1
GO
SELECT COUNT(DISTINCT Sno)
FROM SC

Use school1
GO
SELECT AVG(Grade)
FROM SC
WHERE Cno='C01'

Use school1
GO
SELECT MAX(Grade)
FROM SC
WHERE Cno='C01'

Use school1
GO
SELECT SUM(Credit)
FROM SC,Course
WHERE Sno='S01' AND SC.Cno=Course.Cno

验证:


GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组。
分组后聚集函数将作用于每一个组,即每一个组都有一个函数值。
Use school1
GO
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno

Use school1
GO
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*)>=3

Use school1
GO
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=80

Use school1
GO
SELECT Student.*,SC.*
FROM Student,SC
WHERE Student.Sno=SC.Sno

Use school1
GO
SELECT Student.Sno,Sname
FROM Student,SC
WHERE Student.Sno=SC.Sno AND SC.Cno='C02' AND SC.Grade>90

连接操作不仅可以在两个表中进行,也可以是一个表与其自己进行连接,称为表的自身连接。
Use school1
GO
SELECT FIRST.Cno,SECOND.Pre_Cno
FROM Course FIRST,Course SECOND
WHERE FIRST.Cno=SECOND.Pre_Cno

在“查询每个学生及其选修课程的情况”中,没有选课的学生没有数据,如果想要这些学生的数据,而选课填上空值NULL,则可以使用外连接:
Use school1
GO
SELECT Student.Sno,Sname,Cno,Grade
FROM Student LEFT OUTER JOIN SC ON (Student.Sno=SC.Sno)

Use school1
GO
SELECT Student.Sno,Sname,Cname,Grade
FROM Student,SC,Course
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno

在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。
将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。
Use school1
GO
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname='李伟'
)

Use school1
GO
SELECT Sno,Sname
FROM Student
WHERE Sno IN
(SELECT Sno
FROM SC
WHERE Cno IN
(SELECT Cno
FROM Course
WHERE Cname=' 数据库'
)
);

Use school1
GO
SELECT Sno,Cno
FROM SC x
WHERE Grade >= (SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno
)

Use school1
GO
SELECT Sname,Sage
FROM Student
WHERE Sage>ANY(SELECT Sage
FROM Student
WHERE Sdept='计算机')
AND Sdept<>'CS'

带有EXITS谓词的子查询不返回任何数据,只产生逻辑真值true或逻辑假值false
Use school1
GO
SELECT Sname
FROM Student
WHERE EXISTS(
SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='C01'
)

使用存在量词EXISTS后,若内层查询结果非空,则外层的WHERE子句返回真值,否则返回假值。
Use school1
GO
SELECT Sname
FROM Student
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='C01'
)

SQL中没有全称量词,可以将题目的意思转换成等价的用存在量词的形式:
查询这样的学生,没有一门课程是他不选修的
Use school1
GO
SELECT Sname
FROM Student
WHERE NOT EXISTS(
SELECT *
FROM Course
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno=Course.Cno
)
)
答案是并没有这样的卷王

SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作。
集合操作主要包括并操作UNION、交操作INTERSECT和差操作EXCEPT
注意,参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同
Use school1
GO
SELECT *
FROM Student
WHERE Sdept='数学'
UNION
SELECT *
FROM Student
WHERE Sage<=19

本例即查询选修课程1与选修课程2的学生集合的并集
Use school1
GO
SELECT Sno
FROM SC
WHERE Cno='C01'
UNION
SELECT Sno
FROM SC
WHERE Cno='C02'

Use school1
GO
SELECT *
FROM Student
WHERE Sdept='数学'
INTERSECT
SELECT *
FROM Student
WHERE Sage<=19

就是查询选修课程1的学生集合与选修课程2的学生集合的交集
Use school1
GO
SELECT Sno
FROM SC
WHERE Cno='C01'
INTERSECT
SELECT Sno
FROM SC
WHERE Cno='C02'

Use school1
GO
SELECT *
FROM Student
WHERE Sdept='数学'
EXCEPT
SELECT *
FROM Student
WHERE Sage<=19
