简单表的查询,嵌套查询,相关子查询,无关子查询

SELECT查询语句

SELECT [ALL|DISTINCT] [TOP n[PERCENT]]<目标表达式>[, ... n]
[INTO <新表名>]
FROM <表名>|<视图>[, ... n]
[WHERE <条件表达式>]
[GROUP BY <列名1>[HAVING <条件表达式>]]
[ORDER BY <列名2> [ASC|DESC]]
  • ALL——(没有则默认) 表示输出所有记录,包括重复
  • DISTINCT——表示输出无重复结果的记录
  • TOP n[PERCENT]指定返回查询结果的前n行数据,如果指定PERCENT关键字,则返回前n%行
  • GROUP BY<列名1>——按照<列名1>的值进行分组
  • ORDER BY<列名2>[ASC|DESC]——按<列名2>排序,ASC为升序,DESC为降序,默认升序

简单查询

查询所有学生的学号和姓名

SELECT 学号,姓名
FROM 学生

查询学生全部信息

SELECT *
FROM 学生

查询计算后的值

SELECT 姓名,YEAR(GETDATE())-YEAR(生日) AS '年龄' --AS后可用于命名计算后新列
FROM 学生

WHERE子句查询

查询全体男生的姓名

SELECT 姓名
FROM 学生
WHERE 性别='男'

查询计算机类,艺术类的课程名

SECELT 课程名
FROM 课程
WHERE 类别 IN('计算机类','艺术类') --若查询除计算机类和艺术类的课用 NOT IN

查询年龄在11和20间的学生姓名

SECELT 姓名
FROM 学生
WHERE YEAR(GETDATE())-YEAR(生日) BETWEEN 11 AND 20

查询姓'朱'学生的姓名和学号

SECELT 姓名,学号
FROM 学生
WHERE 姓名 LIKE '朱%'

查询姓'朱'的男学生姓名和学号

SECELT 姓名,学号
FROM 学生
WHERE 姓名 LIKE '朱%' AND 性别 = '男'

ORDER BY子句查询

ORDER BY <列名>|表达式 ASC|DESC --ASC升序,DESC降序,默认升序

查询按照年龄倒序的学生姓名和年龄

SELECT 姓名,YEAR(GETDATE())-YEAR(生日) AS '年龄'
FROM 学生
ORDER BY YEAR(GETDATE())-YEAR(生日) DESC

GROUP BY子句查询

统计有多媒体教室和无多媒体教室分别有多少座位

SELECT 多媒体 AS '多媒体',SUM(座位) AS '座位'
FROM 教室
GROUP BY 多媒体

联合查询

查询选修了001或002课程号的学生的学号

或:UNION

SELECT 学号
FROM 选修
WHERE 课程号 = '001'
UNION
SELECT 学号
FROM 选修
WHERE 课程号 = '002'

查询选修了001和002课程号两门的学生的学号

交:INTERSECT

SELECT 学号
FROM 选修
WHERE 课程号 = '001'
INTERSECT
SELECT 学号
FROM 选修
WHERE 课程号 = '002'

查询选修了001课程没有选修002课程的学生的学号

差:EXCEPT

SELECT 学号
FROM 选修
WHERE 课程号 = '001'
EXCEPT
SELECT 学号
FROM 选修
WHERE 课程号 = '002'

连接查询

从两个或两个以上的表中对符合某些条件的元组尽心查询操作成为连接查询

1. 内连接

内连接用INNER JOIN连接

SELECT <目标表达式>[,...n]
FROM <表1> [INNER] JOIN <表2> ON <连接表达式>[,...n]

JOIN关键字前没有指定连接类型,默认内连接

例子:查询学生及其选修课程信息

USE JXGL
SELECT *
FROM 选修 INNER JOIN 学生 ON 学生.学号=选修.学号 --ON后可用AND添加条件

两个表之间的连接通过公共属性“学号”实现的

如何将四个表内连接?

USE JXGL
GO
SELECT *
FROM 选修 JOIN 学生 ON 选修.学号 = 学生.学号
JOIN  课程 ON 选修.课程号 = 课程.课程号
JOIN 授课地 ON 选修.课程号 = 授课地.课程号

2. 外连接

2.1 左外连接

左外连接是对连接条件左边的表不加限制。当左边元组表与右边表元组不匹配时,与右边表的相应列值取NULL。

SELECT <目标表达式>[,...n]
FROM <表1> LEFT[OUTER] JOIN <表2> ON<连接条件表达式>[,...n]

例子:查询学生及其选修课程信息(含未选课程的学生信息)

USE JXGL
SELECT *
FROM 学生 LEFT JOIN 选修 ON 学生.学号=选修.学号 --ON后可用AND添加条件
2.2 右外连接

右外连接是对连接条件右边的表不加限制。当右边元组表与左边表元组不匹配时,与左边表的相应列值取NULL。

同一个例子:查询学生及其选修课程信息(含未选课程的学生信息)

USE JXGL
SELECT *
FROM 选修 RIGHT JOIN 学生 ON 学生.学号=选修.学号 --ON后可用AND添加条件

与左外连接例子输出结果一样,列名排列顺序不同

2.3 全外连接

全外连接是对连接条件的两个表都不加限制。当一边表元组与另一边表元组不匹配时,另一边取值NULL。

SELECT <目标表达式>[,...n]
FROM <表1> FULL [OUTER] JOIN <表2> ON<连接条件表达式>[,...n]

3. 交叉连接

交叉连接:没有连接条件下的两个表的连接,包含了所连接的两个表中所有元组的全部组合。(不经常使用)

SELECT <目标表达式>[,...n]
FROM <表1> CROSS JOIN <表2> ON<连接条件表达式>[,...n]

嵌套查询(子查询)

1.无关子查询

无关子查询的执行不依赖于父查询。执行过程:首先执行子查询,得到结果传递给父查询使用

例子:查询选修了课程名为’电子商务’ 的学生的学号和姓名

USE JXGL
SELECT 学号,姓名
FROM 学生
WHERE 学号 IN
(
SELECT 学号
FROM 选修
WHERE 课程号 IN
(
SELECT 课程号
FROM 课程
WHERE 课程名 = '电子商务'
)
)

2.相关子查询

相关子查询中,子查询的执行依赖于父查询。

相关子查询与无关子查询的区别:无关子查询仅此执行一次,而相关子查询查询中的子查询需要重复执行。

2.1 带有比较运算符的子查询

将一个表达式的值与子查询返回的单个值进行比较,若比较结果为TRUE,则比较测试返回TRUE

例子:查找比王刚年龄小的人

SELECT 学号,姓名,年龄
FROM 学生
WHERE 年龄<
(
SELECT 年龄
FROM 学生
WHERE 姓名 = '王刚'
)
2.2 带有EXISTS的子查询

带有存在性测试EXISTS的子查询不返回数据,只产生逻辑值TRUE或FALSE,因此由EXISTS引出的子查询,其目标表达式一般用'*'表示。如果子查询结果不空,则父查询的WHERE子句条件为TRUE,否则为FALSE。NOT EXISTS则相反。

例子1解析:

父查询中将a学生信息传递给子查询,子查询中WHERE进行条件对比:

若学生a年龄 = 学生b年龄,则子查询结果不为空,NOT EXISTS返回FALSE,不符合

若学生a年龄 <>学生b年龄,则子查询结果为空,NOT EXISTS返回TRUE,输出该学生学号,姓名,年龄

例子1.查询与其他所有学生年龄均不同的学生学号, 姓名和年龄

SELECT 学号,姓名,年龄
FROM 学生 AS a
WHERE NOT EXISTS
(
SELECT *
FROM 学生 AS b
WHERE a.年龄 = b.年龄 AND a.学号<>b.学号 --不能与自己相比,不然没意义
)

例子2. 查询没有人选修的课程号和课程名:

SELECT 课程号,课程名
FROM 课程
WHERE NOT EXISTS
(
SELECT *
FROM 选修
WHERE 课程号 = 课程.课程号
)

例子3.查询选修了全部课程的学生姓名

SELECT 姓名
FROM 学生
WHERE NOT EXISTS
(
SELECT *
FROM 课程
WHERE NOT EXISTS
(
SELECT *
FROM 选修
WHERE 课程号 = 课程.课程号 AND 学号 = 学生.学号
)
)

统计查询

聚集函数

  • COUNT() 求个数
  • AVG() 求平均数
  • SUM() 求总和
  • MAX() 求最大值
  • MIN() 求最小值

例1 查询学生总人数

USE JXGL
SELECT COUNT(*)
FROM 学生

例2 查询选修了课程的学生总数

USE JXGL
SELECT COUNT(学号)
FROM 学生
WHERE EXISTS
(
SELECT *
FROM 选修
WHERE 学号 = 学生.学号
)

例3 查询所有课程的总学分数和平均学分数,以及最高学分和最低学分

USE JXGL
SELECT SUM(学分) AS 总学分,AVG(学分) AS 平均学分,MAX(学分) AS 最高学分,MIN(学分) AS 最少学分
FROM 课程

分组查询

GROUP BY子句查询

将查询结果按属性列或属性组合对元组进行分组。

带HAVING子句的分组查询

当完成数据结果的查询和统计后,可以使用HAVING关键字来对查询和统计结果进行进一步的筛选

例1 查询各系的男女生学生总数, 并按系别,升序排列, 女生排在前

USE JXGL
SELECT 系编号,COUNT(*) AS 人数,性别
FROM 学生
GROUP BY 系编号,性别
ORDER BY 系编号 ASC,性别 DESC

例2 查询每个学生所选课程的平均成绩, 最高分, 最低分,和选课门数

USE JXGL
SELECT 学号,AVG(成绩) AS 平均分,MAX(成绩) AS 最高分,MIN(成绩)AS 最低分,COUNT(课程号) AS 课程种类
FROM 选修
GROUP BY 学号

例3 查询平均分超过80分的学生的学号和平均分

USE JXGL
SELECT 学号,AVG(成绩)AS 平均成绩
FROM 选修
GROUP BY 学号
HAVING AVG(成绩)>80