这篇博客主要介绍SQl基本查询语句
下面是查询基于的表
Student表
SC表
Course表
下面是具体的代码
1.创建表
CREATE TABLE Student( //创建学生表
Sno CHAR(15) PRIMARY KEY, //指定主码
Sname CHAR(20) UNIQUE, //唯一性约束条件
Ssex CHAR(6),
Ssage CHAR(6),
Sdept CHAR(6)
)
CREATE TABLE Course( //创建课程表
Cno CHAR(20) PRIMARY KEY,
Cname CHAR(20),
Cpno CHAR (20),
Ccredit CHAR(10)
FOREIGN KEY (Cpno) REFERENCES Course(Cno) //外码的大小必须和依赖的码大小相同,否则会出现不一致的现象,无法创建外码
)
CREATE TABLE SC //创建选课表
(
Sno CHAR(15),
Cno CHAR(20),
Grade CHAR(5)
PRIMARY KEY(Sno,Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno)
)
1单表查询
1.1 查询表中的某一列
SELECT 列名
FROM 表名
eg:
SELECT Sno,Sname,Sdept //查询学生学号,姓名,系
FROM Student
1.2 查询经过计算的值
SELECT 2017-Ssage '年龄' //查询学生的年龄,由于是计算值,所以计算完成后没有表名。需要额外的加入表名
FROM Student
1.3 查询表中元祖
SELECT DISTINCT Sno //查询选修课的学号,用distinct消除重复
FROM SC
1.4 查询满足条件的元祖
常用的满足条件的元祖有,比较>,<,=,<>,确定范围的BETWEEN AND,NOT BETWEEN AND,确定集合的IN,NOT IN,字符匹配的LIKE,NOT LIKE
SELECT Sno,Sname,Ssage
FROM Student
WHERE Sno>19 查询年龄大于19的, WHERE Ssage BETWEEN 19 AND 20 //查询年龄在 19到20之间的
SELECT Sno,Sdept //查询在IS和CS系的学生
FROM Student
WHERE Sdept IN('IS','MA') //IN和等于的区别, 当IN里面只有一个元素的时候,和=是等价的,其余不等价
字符匹配查询
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '李%' //%号查询是匹配任意长度, _划线查询是匹配单个字符长度
SELECT Sname,Sno //如果出现like后面有和_一样的符号,需要用转义字符来区分
FROM Student
WHERE Sname LIKE '李&_勇' ESCAPE '&'
1.5 ORDER BY 语句
按一个或者多个属性进行排列,ASC升序,DEC降序,默认升序
SELECT Sno,Grade
FROM SC
ORDER BY Grade DESC
1.6 聚集函数
聚集函数是数据库提供的一组用于计算的函数,它有COUNT(统计数量),SUM(计算总和),AVG(求平均值),MAX(求最大值),MIN(求最小值),
SELECT COUNT(Sno) '人数' //求人数
FROM Student
1.7 GROUP BY
GROUP BY 是对聚集函数的细化,如果没有GROUP BY,聚集函数作用的是整张表,有了GROUP BY 可以按照分组来进行划分
SELECT Cno,COUNT(Sno) '人数' //查询选修各门课的人数,SELECT后面的元素,必须在group by 里面,或者 聚集函数里面
FROM SC
GROUP BY Cno
1.8 HAVING和WHERE的区别
SELECT Sno //查询选修课大于三门课的同学的学号
FROM SC
GROUP BY Sno
HAVING COUNT(Sno)>=3
HAVING作用于表或视图。WHERE作用于分祖。
2 连接查询
当涉及多个表的查询的时候,可以采用连接查询
2.1 等值连接,非等值连接,自然连接
等值连接是两张表里面找出相等的两列
自然连接是把重复的列去掉
SELECT Student.*,SC.Cno,SC.Grade //这是自然连接,表中没有重复的列。如果把SC换成SC.*,那么就是等值连接
FROM Student,SC
WHERE Student.Sno=SC.Sno
2.2 自身连接
如果一张表自己和自己相连,那么就是自身连接,自身连接的时候必须起别名来区分第一张表和第二张表。因为涉及两张表的,所以他们的同名属性要加别名区分。
SELECT First.Cno,First.Cname,Second.Cno,Second.Cname //查询每一门课程的先行课,这里用Second.Cno而不用Second.Cpno可以避免选修课为空的情况
FROM Course First,Course Second
WHERE FIRST.Cpno=Second.Cno
2.3 外连接
普通连接只会把满足条件的元组输出,而外连接可以把不满足条件的元组也输出。如输出学生选修课的成绩,普通连接只是会输出有成绩的学生,外连接可以输出没有成绩的学生
外链接分为左外连接(列出左边的所有元组),右外链接(列出右边的所有元组),全连接(列出左边右边全部的元组)
SELECT Student.Sno,Ssex,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC ON(Student.Sno=SC.SnO)
2.4 复合条件连接,多表连接
连接的时候where语句有好多条件,中间用AND连接。
多表连接和复合条件连接有相似的地方,比如三张表连接,连接的时候,两张表两张表的连接,最后用AND连接起来
SELECT Student.Sno,Sname
FROM Student,SC
WHERE Student.Sno=SC.Sno AND Grade>90
3 嵌套查询
一个SELECT-FROM-WHERE是一个查询块,将一个查询块放在另一个查询的where或者,having里,为嵌套查询
相关子查询,不相关子查询 子查询不依赖于父查询为不相关子查询,依赖于子查询为相关子查询
3.1 带有IN谓词的嵌套查询
SELECT Sno //查询选修课成绩大于90分的学生的学号
FROM Student
WHERE Sno IN(
SELECT Sno
FROM SC
WHERE Grade>=90
)
//查询选修了信息系统这门课的学生的学号和姓名
SELECT Sno,Sname //这是一个不相关的子查询,
FROM Student
WHERE Sno IN(
SELECT Sno
FROM SC
WHERE Cno IN (
SELECT Cno
FROM Course
WHERE Cname='信息系统'
)
)
对于不相关子查询也可换成连接查询
SELECT Student.Sno,Sname
FROM Student,SC,Course
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno AND Course.Cname='信息系统'‘
3.2 带有比较符的嵌套查询
SELECT Sno,Cno //相关子查询,如果涉及一张表里的属性在父查询和子查询中都出现。必须要加入别名
FROM SC x //查询每门课程中大于自己选修课平均分的课程
WHERE Grade>=(
SELECT AVG(Grade)
FROM SC y
WHERE X.Sno=Y.Sno
)
3.3 带有ANY,ALL谓词的子查询
ANY是任何一个,all是所有,在应用的时候,往往和比较运算符来结合使用
>any,比最小的元素大(等价于>MIN),>all,比最大的元素(等价于>MAX),,比最大的元素小(等价于<MAX),<all,比最小的元素小(等价于<MIN)
SELECT Sno,Sname //查询除了IS系之外的其他的系的年龄小于IS系中最大的年龄的人
FROM Student
WHERE Ssage<ANY(
SELECT Ssage
FROM Student
WHERE Sdept='IS'
)AND Sdept<>'IS'
下面是等价的式子
SELECT Sno,Sname
FROM Student
WHERE Ssage<(
SELECT MAX(Ssage)
FROM Student
WHERE Sdept='IS'
)AND Sdept<>'IS'
3.4 带有ESTSIS谓词的查询
EXISTS表示存在的意思,他只有true和false的意思,如果内层查询为空,则返回false给where,如果内层查询为非空,则返回true
NOT EXISTS 表示不存在的意思。和上面的正好相反。查询的结果依赖于EXISTS后面是TRUE还是false
//查询选修了一号课程学生的姓名
SELECT Sname
FROM Student
WHERE EXISTS (
SELECT *
FROM SC
WHERE Student.Sno=SC.Sno AND Cno='1'
)
4 集合查询
UNION 并操作,EXCEPT 差操作, INTERSECT 交操作 参加集合的操作的列数必须相同,而且数据类型必须相同
//查询IS系的同学或年龄小于19的同学
SELECT * //UNION 会自动去掉重复的列 UNION ALL 不会去掉重复的列
FROM Student
WHERE Sdept='IS'
UNION
SELECT *
FROM Student
WHERE Ssage<=19 //等价于select后面的语句是where Sdept='IS' or Ssage<=19