SQL 数据查询
SLELECT查询语句
SELECT A1,A2,...An
FROM R1,R2,...Rm
WHERE F;
WHERE子句的条件表达式可以使用下列运算符
·算术比较运算符:<,<=,>,>=,<>,!=
·逻辑运算符:AND,OR,NOT
·集合成员资格运算符:IN,NOT IN
·谓词:EXISTS,ALL,SOME,UNIQUE
·聚合函数:AVG,MIN,MAX,SUM,COUNT
·F中运算还可以是另一个SELECT语句,即SELECT语句可以嵌套
SELECT 目标表列名或列表达式序列
FROM 基本表名和视图序列
[WHERE 行条件表达式]
[GROUP BY 列名序列(除了聚合函数以外所有目标)
[HAVING 组条件表达式]]
[ORDER BY 列名[ASC|DESC],...]
语句执行过程:
- 读取FROM子句中基本表,视图数据,执行笛卡尔积操作。
- 选取满足WHERE子句给出的条件表达式的元组。
- 按GROUP子句中指定列的值分组,同时提取满足子句中组条件表达式的元组。
- 按SELECT子句中给出的列名或列表达式求值输出。
- ORDER子句对输出的目标表进行排序。ASC表示升序,DESC表示降序。
单表查询
查询表中的若干列
查询指定列
SELECT SNO,SNAME
FROM S;
查询经过计算的值
SELECT SNAME,2013-AGE
FROM S;
选择表中若干元组
消除取消重复行
SELECT DISTINCT SNO
FROM S;
查询满足条件的元组
使用WHERE子句限定实现。
查询条件 | 谓词 |
---|---|
比较 | =,<,>,<>,!=,<=,>=,… |
确定范围 | BETWEEN AND,NOT BETWEEN AND |
确定集合 | IN,NOT IN |
字符匹配 | LIKE,NOT LIKE |
空值 | IS NULL,IS NOT NULL |
多重条件(逻辑运算) | AND,OR,NOT |
1. 比较
SELECT SNAME
FROM S
WHERE SNO='1';
2.范围查询
SELECT SNO,SNAME,AGE
FROM S
WHERE AGE BETWEEN 20 AND 23;
相当于
SELECT SNO,SNAME,AGE
FROM S
WHERE AGE>=20 AND AGE<=23;
3.确定集合
SELECT SNO,SNAME,AGE
FROM S
WHERE SDEPT IN('化学系','外语系');
4.字符匹配谓词
% 代表任意长度的字符串
_ 代表任意单个字符
SELECT SNAME,SNO,SEX
FROM S
WHERE SNAME LIKE ’_刘%’;
5.涉及空值的查询例
SELECT SNO,CNO
FROM SC
WHERE GRADE IS NULL; /* 分数GRADE是空值 */
6.多重条件查询
SELECT SNAME
FROM S
WHERE SDEPT=’CS’ AND AGE<20;
排序查询结果
ORDER BY 子句
·可以按一个或多个属性列排序
升序:ASC;
降序:DESC;
缺省值为升序
·当排序列含空值时
ASC:排序列为空值的元组最后显示
DESC:排序列为空值的元组最先显示
聚合函数
计数
COUNT([DISTINCT|ALL] *)
COUNT([DISTINCT|ALL] <列名>)
计算总和
SUM([DISTINCT|ALL] <列名>)
计算平均值
AVG([DISTINCT|ALL] <列名>)
求最大值
MAX([DISTINCT|ALL] <列名>)
求最小值
MIN([DISTINCT|ALL] <列名>)
/* DISTINCT短语:在计算时要取消指定列中的重复值
ALL短语:不取消重复值
ALL为缺省值 */
例
SELECT COUNT(DISTINCT SNO),
FROM SC;
分组查询
SELECT CourseID, AVG(Score) AS 课程平均成绩
FROM Score
GROUP BY CourseID
· 使用HAVING 短语筛选最终输出结果
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*) >3;
总结例
/*查询有3门以上课程是90分以上的学生的学号及(90分以上的)课程数。*/
SELECT Sno, COUNT(*)
FROM SC
WHERE Grade>=90
GROUP BY Sno
HAVING COUNT(*)>=3;
多表查询
连接查询
1.内连接-inner jion :
SELECT S.NAME,M.MARK
FROM STUDENT S,
MARK M
WHERE S.ID=M.STUDENTID;
等价于
SELECT S.NAME,M.MARK
FROM STUDENT S
INNER JOIN MARK M
ON S.ID=M.STUDENTID
2.左连接-left join:
SELECT S.NAME,M.MARK
FROM STUDENT S
LEFT JOIN MARK M
ON S.ID=M.STUDENTID
3.右连接-right join:
SELECT S.NAME,M.MARK
FROM STUDENT S
RIGHT JOIN MARK M
ON S.ID=M.STUDENTID
4.全连接-full join:
SELECT S.NAME,M.MARK
FROM STUDENT S FULL
JOIN MARK M
ON S.ID=M.STUDENTID
嵌套查询
SELECT SNO,SNAME,SDEPT
FROM S
WHERE SDEPT IN
(SELECT SDEPT
FROM S
WHERE SNAME=’刘晨’ );
/*查询与“刘晨”在同一个系学习的学生。*/
SELECT SNO,SNAME /* 外层在S关系中取出SNO和SNAME */
FROM S WHERE SNO IN
(SELECT SNO /* 在SC关系中找出选修了3号课程的学生学号 */
FROM SC
WHERE CNO IN
(SELECT CNO
FROM C
WHERE CNAME=’信息系统’ )
);
/* 在C关系中找出“信息系统”的课程号,结果为3号 */
带有ANY和ALL谓词的子查询
谓词语义
· ANY: 任意一个值
· ALL : 所有值
SELECT SNAME,AGE
FROM S
WHERE AGE<ANY(SELECT AGE
FROM S
WHERE SDEPT=’CS’)
AND Sdept<>’CS’;
EXISTS谓词
带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
· 若内层查询结果非空,则返回真值
· 若内层查询结果为空,则返回假值
SELECT SNAME
FROM S
WHERE EXISTS
(SELECT *
FROM SC /*相关子查询*/
WHERE SNO=S.SNO
AND CNO= '1');
/*查询所有选修了1号课程的学生姓名。*/
SELECT SNAME
FROM S
WHERE NOT EXISTS
(SELECT *
FROM SC
WHERE SNO = S.SNO AND CNO='1');
/*查询没有选修1号课程的学生姓名。*/
/*此例用连接运算难以完成*/
集合操作
交集
形式
<查询块>
UNION
<查询块>
参加UNION操作的各结果表的列数必须相同;对应项的数据类型也必须相同
SELECT *
FROM S
WHERE SDEPT=’CS’
UNION
SELECT *
FROM S
WHERE AGE<=19;
并集
<查询块>
INTERSECT
<查询块>
SELECT SNO
FROM SC
WHERE CNO=’l’
INTERSECT
SELECT SNO
FROM SC
WHERE CNO=’2’;