基础SQL语句总览(库,表,记录)
操作数据库
增:create database db1 charset utf8; 删:drop database db1; 改:alter database db1 charset latin1; 查:show databases;
操作表
增:create table t1 (id int,name char); 删:drop table t1; 改:alter table t1 modify name char(3); alter table t1 change name name1 char(2); 查:show tables;
操作记录(表的内容)
增:insert into t1 values(1,”zhangsan”),(2,”lisi”),(3,”wangwu”); 删:delete from t1 where id=1; 改:update t1 set name=”eagle” where id=3; 查:select * from t1;
1.数据定义
SQL的数据定义功能包含模式、表、视图和索引的创建、删除等操作。
| 操作对象 | 创建 | 删除 | 修改 |
|---|---|---|---|
| 模式 | create schema | drop schema | |
| 表 | create table | drop table | alter table |
| 视图 | create view | drop view | |
| 索引 | create index | drop index | alter index |
1.1模式的定义与删除
定义模式:
create schema <模式名> authorization <用户名>
模式名如果省略则默认模式名与用户名相同
- 例:创建模式Test,用户名为ZHANG,并在模式下创建表TAB1
create schema Test authorization ZHANG
create table TAB1(col1 smallint,
col2 int,
col3 char(10),
col4 numeric(10,3),
col5 decimal(5,2)
);
删除模式:
drop schema <模式名>
cascade代表级联,表示删除模式下的一切数据库。restrict代表限制,表示如果该模式下有数据库对象(表,视图等)就无法删除模式。
- 例:
drop shcema Test cascade;
该语句删除了模式Test和模式中已经定义的表TAB1
1.2表的定义、删除与修改
1.2.1定义表:
create table <表名> (<列名> <数据类型> [完整性约束条件], <列名> <数据类型> [完整性约束条件], [<表级完整性约束条件>]);
- 例学生表student,课程表course和学生选课表sc。
create table student (sno char(9) primary key,
sname char(20) unique,
ssex char(2),
sage smallint,
sdept char(20));
create table course (cno char(4) primary key,
cname char(40) not null,
cpno char(4), //cpno的含义是先修课
ccredit smallint,
foreign key(cpno) references course(cno)); //表级完整性约束条件,被参照表course, 被参照列cno
注:参照表和被参照表可以是同一张表
create table sc (sno char(9),
cno char(4),
grade smallint,
primary key (sno,cno), //主码由两个属性构成,必须作为表级完整性约束条件定义
foreign key (sno) references student (sno),
foreign key (cno) references course (cno));
数据类型
| 数据类型 | 含义 |
|---|---|
| char(n) | 长度为n的定长字符串 |
| varchar(n) | 最大长度为n的变长字符串 |
| int | 长整数(4字节) |
| smallint | 短整数(2字节) |
| bigint | 大整数(8字节) |
| numeric(p,d) | 定点数,由p位数字组成,小数点后d位数字 |
| decimal(p,d),dec(p,d) | 同numeric(p,d) |
| float(n) | 可选精度浮点数,精度至少n位数字 |
| boolean | 逻辑布尔量 |
| date | 日期,包含年月日,格式为YYYY-MM-DD |
| time | 时间,包含一日的时分秒,格式为HH:MM:SS |
1.2.2修改表:
alter table <表名> add <新列名> <数据类型> [完整性约束条件]; alter table <表名> drop <列名> [cascade | restrict]; alter table <表名> alter column <列名> <数据类型>; alter table <表明> add <表级完整性约束> ;
- 例:向student表中添加入学时间列,数据类型为日期
alter table student add s_entrance date;
- 例:将年龄由字符型改为整型
alter table student alter column sage int;
- 例:增加课程名称必须取唯一值的约束条件
alter table course add unique(cname)
1.2.3删除表:
drop table <表名> [cascade | restrict]
restrict表示该表的删除不能被其他约束引用,不能有视图,不能有存储过程或函数等。否则不能删除该表。
casecde表示表的删除没有限制条件,相关的依赖对象都会被删除。
默认情况是restrict
1.3视图的定义与删除
1.3.1定义视图:
create view <视图名> [(<列名>)] as <子查询> [with check option];
- 例:建立信息系学生视图
create view is_student
as
select sno,sname,sage
from student
where sdept=’is’;
with check option;
加上with check option子句后,以后对该视图进行插入、修改和查询时关系数据库管理系统会自动加上sdept=’is’条件。
1.3.2删除视图
drop view <视图名> [cascade];
1.3.3查询视图
- 例:在信息系学生的视图中查找年龄小于20的学生
select sno,sage
from is_student
where sage<20;
- 例:在s_g视图查询平均成绩在90分以上的同学
select sno,avg(grade)
from sc
where avg(grade)>=90
group by sno;
上面的写法会报错,因为where子句中是不能以聚集函数作为表达式的,正确的语句是:
select sno,avg(grade)
from sc
group by sno
having avg(grade)>=90;
1.4索引的建立与删除
create [unique] [cluster] index <索引名> on <表名>(<列名>[<次序>]);
- 例:sc表按学号升序和课程号降序建唯一索引
create unique index scno on sc(sno asc,cno desc);
alter index <旧索引名> rename to <新索引名>; drop index <索引名>
2.数据查询
2.1单表查询
2.1.1查询表中若干列
(1)查询指定列
- 例:查询全体学生的学号和姓名
select sno,sname
from student;
(2)查询全部列
- 例:查询全体学生的详细记录
select *
from student;
(3)查询经过计算的值
- 例:查询全体学生姓名及其出生年份(假设当前为2020年)
select sname,2020-sage
from student;
2.1.2选择表中的若干元组
(1)消除取值重复的行
select distinct sno
from sc;
(2)查询满足条件的元组
select sname,sage
from student
where sage<20;
- 查询年龄在20-30岁之间的学生的姓名,系别和年龄
select sname,sdept,sage
from student
where sage between 20 and 30;
- 查询数学系(MA)和信息系(IS)学生的姓名和性别
select sname,sex
from student
where sdept in (‘MA’,’IS’);
- 查询名字中第二个字为“阳”的学生的姓名和学号
select sname,sno
from student
where sname like ‘_阳%’;
通配符%代表任意长度(长度可以为零)的字符串 通配符_代表任意单个字符
- 查询DB_Design课程的课程号和学分
select cno,credit
from course
where cname like ‘DB_Design’ esacpe ‘\’;
‘\’是换码字符,紧跟在其后的字符不再具有通配符的含义,转义为普通字符
2.1.3order by子句
- 同一系中学生按年龄排序
order by sdept,sage desc;
desc降序 asc升序
2.1.4聚集函数
count(*) 统计元组个数
count( [distinct | all] <列名>) 统计一列中值的个数
sum( [distinct | all] <列名>) 计算一列中值的总和
avg( [distinct | all] <列名>) 计算一列中值的平均值
max( [distinct | all] <列名>) 求一列值中的最大值
min( [distinct | all] <列名>) 求一列值中的最小值
2.1.5 group by子句
group by 子句将查询结果按某一列或多列的值分组,值相等的为一组。
- 求各个课程号及相应的选课人数
select cno,count(sno)
from sc
group by cno;
该语句对查询结果按cno的值分组,值相同的为一组,然后对每一组作用聚集函数count进行计算。
查询结果:
| cno | count(sno) |
|---|---|
| 1 | 22 |
| 2 | 34 |
| 3 | 44 |
| 4 | 33 |
若分组后还要按条件筛选使用having而不能使用where
- 查询成绩大于90分的学生学号和平均成绩
错误:
select sno,avg(grade)
from sc
where avg(grade)>90
group by sno;
正确:
select sno,avg(grade)
from sc
group by sno
having avg(grade)>90;
2.2连接查询
2.2.1等值连接和非等值连接
查询条件连接运算符为‘=’时为等值连接,使用其他运算符为非等值连接。
- 例:查询每个学生及其选课情况
select student.,sc.
from student.sc
where student.sno=sc.sno
- 例:查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
select student.sno,sname
from student,sc
where student.sno=sc.sno and cno=’2’ and sc.grade>90;
2.2.2自身连接
- 例:查询每门课的间接先修课(即先修课的先修课)
分析:在course表中有每门课的先修课信息,而没有先修课的先修课。将course去两个别名:first和second
select first.cno,second.cpno
from course first,course second
where first.cpno=second.cno
2.2.4外连接
- 例:
select student.sno,sname,cno,grade
from student left outer join sc on (student.sno=sc.sno);
| student.sno | sname | cno | grade |
|---|---|---|---|
| 1 | 李勇 | 1 | 92 |
| 1 | 李勇 | 2 | 85 |
| 1 | 李勇 | 3 | 88 |
| 2 | 刘晨 | 2 | 90 |
| 2 | 刘晨 | 3 | 80 |
| 3 | 王敏 | null | null |
| 5 | 张力 | null | null |
- 例:
select student.sno,sname,cno,grade
from student right outer join sc on (student.sno=sc.sno);
| student.sno | sname | cno | grade |
|---|---|---|---|
| 1 | 李勇 | 1 | 92 |
| 1 | 李勇 | 2 | 85 |
| 1 | 李勇 | 3 | 88 |
| 2 | 刘晨 | 2 | 90 |
| 2 | 刘晨 | 3 | 80 |
左外连接列出左边关系中的所有元组,右外连接列出右边关系中的所有元组。
2.3 嵌套查询
2.3.1带有In谓词的子查询
- 例:查询选修了课程名为“信息系统”的学生学号和姓名
select sno,sname
from student
where sno in
(select sno from sc where cno in
(select cno from course where cname=’信息系统’)
);
2.3.2带有比较运算符的子查询
- 例:找出每个学生超过他自己选修课程平均成绩的课程号
select sno,cno
from sc x
where grade>=(select avg(grade)
from sc y
where y.sno=x.sno);
子查询的查询条件依赖于父查询,是相关查询,否则为不相关子查询。
2.3.3any、all和exists
any 某个值
all 所有值
any和all必须同时使用比较运算符。
exists内层查询结果非空,则外层where子句返回真值,否则返回假值。
not exists内层查询结果为空,则外层where子句返回真值,否则返回假值。
- 例:查询所有选修了1号课的学生姓名
select sname
from student
where exists
(select *
from sc
where sno=student.sno and cno=’1’);
- 例:查询所有没有选修1号课的学生的姓名。
select sname
from student
where not exists
(select *
from sc
where sno=student.sno and cno=’1’);
2.3.4集合查询
并操作(UNION)、交操作(INTERSECT)、差操作(EXCEPT)
- 例:查询计算机科学系的学生及年龄不大于19岁的学生
select
from student
where sdept=’cs’
union
select
from student
where sage<=19;
- 例:查询计算机科学系中年龄不大于19岁的学生
select
from student
where sdept=’cs’
intersect
select
from student
where sage<=19;
- 例:查询计算机科学系中年龄大于19岁的学生
select
from student
where sdept=’cs’
except
select
from student
where sage<=19;
2.3.5基于派生表的查询
- 例:查询所有选修了1号课的学生姓名
slelect sname
from student,(select sno from sc where cno=’1’) as sc1
where student.sno=sc1.sno;
通过from子句生成派生表时as关键词可以省略,但是必须为派生表指定一个别名。
3.数据更新
3.1 插入数据
3.1.1插入元组
insret into <表名> [<属性列>] values(<常量>)
3.1.2插入子查询结果
insert into<表名>[<属性列>] 子查询;
- 例:对每一个系,求学生的平均年龄,并把结果存入新表
首先建一个新表:
create table dept_age
(sdept char(15)
avg_age smallint);
然后对student表按系分组求平均年龄,再把系名和平均年龄存入新表:
insert
into dept_age(sdept,avg_age)
select sdept,avg(age)
from student
group by sdept;
3.2 修改数据
update <表名>
set <列名>=<表达式> [where <条件>]
3.3 删除数据
delete from <表名> [where<条件>]
