数据库第一周

第四章 结构化查询语言

因为学校的弱智安排,第一周要上机,所以从第四章开始讲

数据库里不做排序的,用的是索引提高查询速度 (因为排序会造成数据冗余)

SQL组成:

数据定义:CREATE,ALTER,DROP

查询语句:SELECT

HAVING(分组,和分组有关用这个)WHERE(选行,分组没关用这个)

基本查询(都是单表查询):

1
2
3
4
5
SELECT sno,sname FROM s; //从s表查sno sname
SELECT * FROM s; //查询s表所有信息 *表示所有
SELECT sname,2021-age 出生年份 FROM s;//查学生名字和出生年份
//表达式取名字 1.字段 AS 名称 2.字段 名称
SELECT distinct sno FROM sc; //distinct 去除重复行

查询——选择行:多个WHERE

通配符:%多个字符, _单个字符

LIKE是模糊匹配,=是精确匹配

1
2
3
4
5
6
7
8
SELECT * FROM s WHERE age<2021-1995; //查询年龄小于2021-1995
SELECT sname FROM s WHERE age>=20 AND age<=25; // 数据在两者之间可以用BETWEEN AND
SELECT sname FROM s WHERE age BETWEEN 20 AND 25;
SELECT sno,grade FROM sc WHERE cno='c1' OR cno='c4' OR cno='c6';// IN 的运算符判断前值是否在后集合
SELECT sno,grade FROM sc WHERE cno IN ('c1','c4','c6');//所有字符型数据一定要加单引号
SELECT sno FROM sc WHERE grade IS NULL;//判断成绩为空
SELECT sname FROM s WHERE sname LIKE '%敏%';
SELECT sname FROM s WHERE sname LIKE '刘__' OR sname LIKE '王__';

单表查询——聚合函数:

1.COUNT——统计行的个数,count+列名 统计该列值的个数

2.SUM——该列求和 AVG MAX MIN

1
2
3
4
5
SELECT COUNT(distinct sno) AS 人数 FROM sc;
SELECT COUNT(*) 次数 FROM sc;
SELECT MAX(age) AS 老大,MIN(age) AS 老小 FROM s;//最大最小
SELECT COUNT(sno) FROM s WHERE age>=19 AND sex='女';
SELECT AVG(grade) 平均分,SUM(grade) 总分 FROM sc WHERE sno='s1';

单表查询——分组排序:

查询结果分组:

1
2
SELECT COUNT(sno) FROM sc GROUP BY cno;//这样写只有一堆数字
SELECT cno,COUNT(sno) FROM sc GROUP BY cno;//这样写才在前面有课程号

SQL规定:GROUP BY出现的列名 一定要在SELECT里出现

SQL Server规定:SELECT里写的GROUP BY里要出现,但不一定代表按此分组

1
2
3
SELECT sno FROM sc GROUP BY sno HAVING count(cno)>1; //选课超过一个的学生学号
SELECT sex,COUNT(sno),AVG(age) FROM s GROUP BY sex;
SELECT sno FROM sc GROUP BY sno HAVING MIN(grade)>70 ;//每门课都超过七十分

查询结果排序:

1
2
SELECT cno,count(sno),SUM(grade) FROM sc GROUP BY cno ORDER BY 3 ASC,2 DESC; //SELECT后面的顺序
SELECT sno,count(cno) FROM sc GROUP BY sno HAVING COUNT(cno)>5 ORDER BY 2 DESC, 1 ASC;//默认升序

多表查询(大的要来了)

联接操作:

INNER JOIN 内联接(两张表要有相同的,张三和张三接一起)

CROSS JOIN 交叉联接(啥关系也没有连一起)

自身联接:

1
2
3
SELECT sno FROM sc GROUP BY sno HAVING COUNT(cno)>=2;
SELECT DISTINCT x.sno FROM sc x,sc y WHERE x.sno=y.sno AND x.cno<>y.cno;//自身联接 同一个人的课程号不同
SELECT DISTINCT x.sno,sname FROM s,sc x,sc y WHERE s.sno=x.sno AND s.sno=y.sno AND x.cno='c1' AND y.cno='c2';

复合条件联接:

1
2
3
SELECT sname,grade FROM s,sc,c WHERE s.sno=sc.sno AND c.cno=sc.cno AND cname='VB' AND grade>70;//查修了VB且超70
SELECT s.sno,sname FROM s,sc WHERE s.sno=sc.sno GROUP BY s.sno HAVING min(grade)>70
SELECT sno,sname,count(cno) FROM s,sc WHERE s.sno=sc.sno GROUP BY s.sno HAVING COUNT(cno)>5 ORDER BY 3 DESC,1