关系数据库标准语言SQL入门

关系数据库标准语言SQL

3.1 SQL概述

3.1.2 SQL的特点

  • 高度非过程化

  • 功能完并且一体化

  • 统一的语法结构

  • 语言简洁,易学易用

    ​ 数据查询:SELECT

    ​ 数据定义:CREATE,DROP

    ​ 数据操作:INSERT,UPDATE,DELETE

    ​ 数据控制:GRANT,REVOKE

3.2 SQL的定义功能

3.2.1基本表的定义

1.表结构的定义
CREATE TABLE<表名>
(<列名><数据类型>[列表完整性约束条件]
 [,<列名><数据类型>[列表完整性约束条件]···]
 [,<表级完整性约束条件>]
);
  • 表名是所要定义的基本表的名字,表可以由一个或多个属性(列)组成
  • 定义表的各个列时需要指明其数据类型及长度
SQL 92提供的主要数据类型
类型 数据类型举例及缩写 说明
Binary BLOB 以十六进制格式存储二进制字符串的值
BitString BIT(n)
BIT VARYING(n)
这两种数据类型可以存储二进制和十六进制数据
Boolean BOOLEAN true、false或unknow
Character CHAR(n)
VARCHAR(n)
存储适宜的字符集中的任意字符组合
Numeric INTEGER
SMALLINT
DECIMAL(i,j)
FLOAT(p,s)
REAL
DOUBLE PERCISION
这些数据类型存储数据的准确值(整数或小数)或近似值
Temporal DATE
TIME
TIMESTAMP
INTERVAL
这些数据类型处理时间的值
  • 完整性约束条件:Primary Key Foreign Key

【例3-1】

CREATE TABLE 学生
(学号 char(8) NOT NULL UNIQUE,
 姓名 char(8),
 性别 char(2),
 出生年份 SMALLINT,
 籍贯 char(8),
 学院 char(15));
2.主关键词的定义
(1)在列出关系模型的属性时,在属性及其类型后加上保留字PRIMARY KEY
(2)在列出关系模型的所有属性后,再附加一个声明:
PRIMARY KEY(<属性1>[,<属性2>,···])

【例3-2】

  • 方法一
CREATE TABLE 学生
(学号 char(8) PRIMARY KEY,
 姓名 char(8),
 性别 char(2),
 出生年份 SMALLINT,
 籍贯 char(8),
 学院 char(15));
  • 方法二
CREATE TABLE 学生
(学号 char(8),
 姓名 char(8),
 性别 char(2),
 出生年份 SMALLINT,
 籍贯 char(8),
 学院 char(15)
 PRIMARY KEY(学号));

【例3-3】

CREATE TABLE 课程
(课程号 SMALLINT NOT NULL UNIQUE,
 课程名 char(15),
 学时  SMALLINT,
 开课学期 char(4),
 课程性质 char(15),
 primary key(课程号));

【例3-4】

CREATE TABLE 学习
(学号 char(8),
 课程号 char(8),
 成绩 smallint,
 primary key(学习,课程号));
3. 外部关键字的定义
(1)如果外部关键词只有一个属性,可以在它的属性名和类型后面直接用REFERENCES说明它参照了某个表的某些属性(必须是PRIMARY KEY
REFERENCES <表名> (<属性>)
(2) 在属性列后面添加
FOREIGN KEY(<属性 1>REFERENCES<表名>(<属性2>))

【例3-5】

CREATE TABLE 学习
(学号 char(8),
 课程号 char(8),
 成绩 smallint,
 primary key(学习,课程号)
 FOREIGN KEY(学号 references 学生(学号))
 FOREIGN KEY(课程号 references 课程(课程号));
4.默认值的定义
性别 char(2) default '男';
年龄 smallint default 19;

3.2.2 基本表的修改和删除

ALTER TABLE 学生 ADD COLUMN 年龄 SMALLINT;

ALTER TABLE 课程 ALTER COLUMN 课程名 CHAR(20);

ALTER TABLE 学生 DROP COLUMN 年龄;

DROP TABLE <表名>

3.2.3 索引的建立和删除

3.3 数据查询

SELECT [ALL|DISTINCT]<属性列表>
FROM <表名或视图名>[,[表名或视图名]]···
[WHERE <条件表达式>]
[GROUP BY <列名>]
[HAVING <条件表达式>]
[ORDER by<列名>[]];

3.3.1 单表查询

  • 选择表中的若干列(投影)
  • 选择表中的若干元组(选择)
  • 对查询进行分组
  • 使用集函数
  • 对查询结果排序
1.SQL中的投影

【例3-12】

SELECT 姓名,籍贯
FROM 学生;

【例3-13】

SELECT DISTINCT 籍贯
FROM 学生;

【例3-14】

SELECT *
FROM 学生;

【例3-15】

查询学生学号和年龄

select 学号,year(now())-出生年份
from 学生;

【例3-16】

给列表别名

select 学号,year(now())-出生年份 as 年龄
from 学生;
2. SQL中的选择运算
常用的查询条件
查 询 条 件 谓 词
比较 =, <>, >, <, >=, <=
算数运算 +,-,*,/
确定范围 BETWEEN AND, NOT BETWEEN AND
确定集合 IN, NOT IN
字符匹配 LIKE, NOT LIKE
空值 IS NULL, IS NOT NULL
多重条件 AND,OR
1)比较运算

【例3-17】

查询所有不及格课程的学生的学号,课程号及成绩

select 学号,课程号,成绩
from 学习
where 成绩<60;

【例3-18】

查询有不及格课程的学生的学号

select distinct 学号
from 学习
where 成绩<60;
2)多重运算和算术运算

【例3-19】

在学生表中找出信电学院2000年后出生的学生的记录

select *
from 学生
where 学院='信电' and 出生年份>2000;
3)确定范围

【例3-20】

select 姓名,性别,学院,出生年份
from 学生
where 出生年份 between 1996 and 1998;
4)确定集合

【例3-21】

select 学号,姓名,出生年份
from 学生
where 学院 in ('信电','理学院','计算机');
5)字符匹配
[not] like '<匹配串>' [ESCAPE'<转码字符>']
6)空值
3.对查询结果进行分组
select 课程号,count(学号) as 选课人数
from 学习
group by 课程号;

【例3-27】

select 学号,count(课程号) as 选修课程数
from 学习
where 学号 between '091501' and '091506' 
group by 学号
having 选修课程数>3;
4.使用集函数
COUNT([DISTINCT|ALL]*) #统计原则个数
COUNT([DISTINCT|ALL]<列名>)#统计一列中值的个数
SUM([DISTINCT|ALL]<列名>)#计算一列值的总和
AVG([DISTINCT|ALL]<列名>)#平均值
MAX([DISTINCT|ALL]<列名>)#最大值
MIN([DISTINCT|ALL]<列名>)#最小值
#查询学生总人数
select count(*)
from 学生; 

#查询计算机学院学生的平均年龄
select avg(year(now())-出生年份) as 平均年龄 #别忘了别名
from 学生
where 学院='计算机';

#查询学习180101号课程的学生最高分数
select max(成绩) as 最高分
from 学习
where 课程号='180101'
5.对查询结果排序
select 学号,成绩
from 学习
where 课程='180102'
order by 成绩 desc;

查询全体学生情况,查询结果按所在学院的名称升序排列,对同一学院中给的学生按年龄降序排列

select *
from 学生
order by 学院 asc, year(now())-出生年份 desc;

3.3.2 连接查询

  • 等值连接和非等值连接
  • 自身连接查询
  • 外连接查询
  • 复合条件连接查询
  • 集合运算查询

(1)ANSI 方式

【例3-33】

#查询每个学生及其选修课程的情况
select 学生.*,学习.*
from 学生 INNER JOIN 学生.学号=学习.学号;

(2) theta方式

select 学生.*,学习.*
from 学生,学习
where 学生.学号=学习.学号;
1.等值与非等值连接查询
[<表名1>.]<列名1><比较运算符>[<表名2>.]<列名> #比较运算符为=时为等值连接
#自然连接“学生表”和“学习表”
select 学生.学号,姓名,性别,出生年份,学院,课程号,成绩
from 学生,学习
where 学生.学号=学习.学号
2.自身连接查询
#求一门课程的间接先修课
select first.课程号 as 课程号,first.课程名 as 课程名,second.课程名 as 间接选修课
from 课程 as first,课程 as second
where first.先修课课程号=second.课程号;
3. 外连接查询
1)左外连接

规定所有记录都应该从连接语句左侧的表中返回。当右侧表中没有匹配的记录时,左表中该记录依然会返回,而右侧表中的列值将自动填充NULL 值

#查询所有学生的姓名以及他们选修课程的课程号和成绩
select 姓名,课程号,成绩
from 学生,学习
where 学生.学号(+)=学习.学号;
2) 右外连接

规定所有记录都应该从连接语句右侧的表中返回。当右侧表中没有匹配的记录时,左表中该记录依然会返回,而右侧表中的列值将自动填充NULL 值

4.复合条件连接查询
#查询选修180101号课程且成绩在90分以上的学生学号,姓名以及成绩
select 学生.学号,姓名,成绩
from 学生,学习
where 学生.学号=学习.学号
and 课程号='180101'
and 成绩>90;

#ANSI
select 学生.学号,姓名,成绩
from 学生 JOIN on 学生.学号=学习.学号
and 课程号='180101'
and 成绩>90;

#查询每个学生及其选修的课程名及其成绩
select 学生.学号,姓名,课程名,成绩
from 学生,课程,学习
where 学生.学号=学习.学号
and 学习.课程号=课程.课程号;

#ANSI
select 学生.学号,姓名,课程名,成绩
from 学生
  JOIN  学习 on 学生.学号=学习.学号
  JOIN  课程 on 学习.课程号=课程.课程号;
5.集合运算连接查询
  • 并:UNION
  • 交:INTERSECT
  • 差:EXCEPT
#查询选修了180101号或180102号课程或二者都选修了的学生学号、课程号和成绩
(select 学生.学号,课程号,成绩
 from 学生,学习
 where 学生.学号=学习.学号 and 课程号='180101')
 union
 (select 学生.学号,课程号,成绩
 from 学生,学习
 where 学生.学号=学习.学号 and 课程号='180102')

3.3.3 嵌套查询

  • 相关子查询
  • 不相关子查询
1. 带有IN谓词的子查询
#查询选修了“数据库原理”课程的学生学号和姓名
select 学号,姓名
from 学生
where 学号 in
(select 学号
 from 学习
 where 课程号 in
(select 课程号
 from 课程
 where 课程名='数据库原理'));
 
#用IN来实现交运算,大部分DBMS不支持INTERSECT
 SELECT 学号,课程号,成绩
 from 学习
 where 课程号='180101' and 学号 in
 (select 学号
  from 学习
  where 课程号='180102' )
  
#NOT IN 差运算
 SELECT 学号,课程号,成绩
 from 学习
 where 课程号='180101' and 学号 not in
 (select 学号
  from 学习
  where 课程号='180102' )
2.带有比较运算符的查询
3.带有ANY或ALL谓词的子查询
#查询其他学院比计算机学院某个学生年龄小的学生名单
select 姓名
from 学生
where year(now())-出生年份 < ANY
(select year(now())-出生年份
 from 学生
 where 学院='计算机')
 and 学院!='计算机'
 order by year(now())-出生年份 desc;
4.带有EXISTS谓词的子查询
#EXISTS实现交运算
SELECT s1.学号,s1.课程号,s1.成绩
from 学习 as s1
where s1.课程号='180101' and exists
(select *
 from 学习 as s2
 where s2.课程号='180102' and s1.学号=s1.学号);
 
#EXISTS实现差运算
SELECT s1.学号,s1.课程号,s1.成绩
from 学习 as s1
where s1.课程号='180101' and not exists
(select *
 from 学习 as s2
 where s2.课程号='180102' and s1.学号=s1.学号);

:¬(BA) 除运算 :\lnot(B-A)

#选修过全部课程的学生的学号和姓名
select 学号,姓名
from 学生
where not exists
(select *
 from 课程
 where not exists
 (select *
  from 学习
  where 学习.学号=学生.学号 and 学习.课程号=课程.课程号 )
)
#查询至少选修了091501号学生选修的全部课程的学生学号
select 学号
from 学生
where not exists
(select *
 from 学习 as First
 where First.学号='091501' and not exists
 (select *
  from 学习 as Second
  where Second.学号=学生.学号 and Second.课程号=First.课程号))

3.4 数据更新

  • 插入
  • 删除
  • 修改

3.4.1 插入数据

1.插入单个元组
INSERT 
INTO <表名> [<属性列>]
Values (<常量1>[,<常量2>···])
INSERT INTO 学习(学号,课程号)
VALUES('091530','080102')
2.插入子查询结果
INSERT
INTO <表名> [<属性列>]
子查询;
#统计每门课的平均分
CREATE TABLE 课程平均分
(课程号 CHAR(8)
 课程名 CHAR(15)
 平均分 DOUBLE);
INSERT 
  INTO 课程平均分(课程号,课程名,平均分)
     SELECT 课程号,课程名,AVG(成绩)
     FROM 课程,学习
     WHERE 课程.课程号=学习.课程号
     GROUP BY 课程号,课程名; 

3.4.3修改数据

UPDATE <表名>
SET <列名>=<表达式>
[WHERE <条件>];
1.更改表中一个元组
UPDATE 学生
SET 籍贯='江苏'
WHERE 学号='091611';
2.更新表中多个元组的数据
#将180101号课程的成绩增加一分
UPDATE 学习
SET 成绩=成绩+1
WHERE 课程号='180101';
3.带子查询的修改
UPDATE 学习
SET 成绩=0
WHERE 学号 IN
(SELECT 学号
 FROM 学生
 WHERE 学院='计算机');

3.5 视图

视图
概念:视图是从一个或几个基本表或视图导出的表
视图也称为虚表或虚关系:只存放视图的定义
视图时一种外模式,从一定程度上提高了视图的安全性

3.5.1 建立视图

create view <视图名>[(<列名>)]
as <子查询>
[WITH CHECK OPTION];

WITH CHECK OPTION表示对视图进行插入、删除和更新操作时要保证发生变动的行慢则视图定义中的谓词条件(即子查询中的条件)

#建立计算机学院选修了“数据库原理”这门课的学生的视图
CREATE VIEW DB_S1
AS
SELECT 学生,学号,姓名,籍贯,学院,成绩
FROM 学习,学生,课程
WHERE 学院='计算机'AND学生.学号=学习.学号 AND 学习.课程号=课程.课程号 and 课程名='数据库原理'

#定义一个反映学生年龄的视图
CREATE VIEW BT_S(学号,姓名,年龄)
as
SELECT 学号,姓名,year(now())-出生年份 AS 年龄
FROM 学生
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章