第一节关系数据库标准语言
1、SQL概述
(1) SQL(structured query language )是结构化查询语言的缩写,是关系数据库的 标准语言。SQL的核心是查询,主要功能为:数据查询(Select) 、数据定义(Create 、 Drop,Alter) 、数据操纵(Insert ,Update , Delete) 、数据控制(Grant , Revoke)
(2) 特点:
A: 是一种一体化的语言
B: 是一种高度非过程化的语言
C: 非常简洁
D: 既可在命令窗口中使用,也可在程序中使用
2、数据查询
(1) 简单查询
A: 格式: select [distinct] 字段名列表from 表名[where 条件]
select 姓名, 性别, 出生日期from zgda
select * from zgda
select distinct 职称from zgda
select distinct 性别, 职称from zgda
select * from zgda where 性别=”女”
select * from zgda where 职称=" 教授"
select * from zgda where 工资>700
select 姓名, 性别, 婚否from zgda where 婚否=.t.
select * from zgda where 职称=" 教授" and 性别="男"
select * from zgda where 性别="男" or 出生日期<={^1975-01-01}
B: 注释:
可用通配符“ * ”来代表所有字段
distinct 表示唯一显示,各个字段值完全一致的相同记录只显示一条记录
where 条件构成了条件查询,如果缺省默认为所有记录
查询窗口可以按ESC键关闭
(2) 几种特殊的运算符
A: in
格式:字段名[not] in (表达式1,表达式2,⋯⋯)
select * from zgda where 职称in(" 教授"," 助教")
select * from zgda where 职称not in(" 助教"," 讲师")
B: between
格式1( 函数) :
[not] between (字段名,表达式1,表达式2)
select * from zgda where between( 工资,500,700)
格式2(短语):
字段名[not] between 表达式1 and 表达式2
字段的取值范围在或不在: >=表达式1 并且<=表达式2
select * from zgda where not between( 奖金,100,200)
C: like
格式1( 函数) : like( 表达式,字段名)
select * from zgda where like(" 王*", 姓名)
格式2( 短语): 字段名like 表达式
select * from zgda where 姓名like “_小_”
(3) 排序
格式:
select [top n [percent] ] [all / distinct] 字段表达式[as 新字段名]
from 表名order by 排序字段列表[asc] / [desc]
①order by 短语的使用, asc 表示升序, desc 表示降序,默认升序
select * from zgda order by 工资
select * from zgda order by 出生日期desc
select * from zgda order by 奖金, 工资desc
select * from zgda where 性别=" 女" order by 奖金desc
②top n [percent] 表示在符合查询条件的所有记录中,选取指定数量或百
分比的记录, Top 短语必须与order by 短语同时使用
select top 3 * from zgda order by 出生日期
select top 2 * from zgda where 婚否=.t. order by 工资desc
③产生新字段的方法,字段表达式as 新字段名
select 姓名, 职称, 工资+奖金as 实发工资from zgda
select 姓名, 性别,year(date())-year( 出生日期) as 年龄from zgda where
职称=" 助教" order by 年龄desc
(4) 分组与计算查询
A: 计算查询
sum(求和字段名)
avg( 字段名)
count(*)
max(字段名)
min( 字段名)
select sum(工资) as 工资合计from zgda
select sum(工资) as 工资合计,avg( 工资) as 平均工资,max( 工资) as 最高工
资,min( 工资) as 最低工资from zgda where 性别=”男”
select count(*) as 职工人数from zgda
select count(*) as 职工人数from zgda where 职称=”教授”
注释:
以上函数均为列项求值;查询中只要有任一个(也可为多个)函数,如果没有 group by 分组,则查询结果只有表中最后一条记录,如果有group by 分组,则 查询结果留下每一类最后一条记录。
如果使用了以上函数,则在查询结果中只有分组字段和统计字段有效,其他字 段均无实际意义。
B: 分组查询:
格式: select 字段表达式[as 新字段名] from 表名where 条件Group by
分类字段having 条件
注释:
①Group by 按列的值对查询的行进行分组,查询结果留下每一类最后一条记录
select 职称,sum( 工资) as 工资合计from zgda group by 职称
select 性别,count(*) as 职工人数from zgda group by 性别
select 职称, 性别,sum( 工资) as 工资合计,count(*) as 人数from zgda group
by 职称, 性别order by 职称desc
②where 短语是指在原表中进行条件筛选,也就是说,只有满足条件的记录才参
与分组。
Select 职称,count(*) as 人数from zgda where 性别=”女”group by 职称
Select 性别,sum( 工资) as 工资合计from zgda where 职称=”讲师” group by
性别
select 职称, 性别,sum( 工资+奖金) as 工资总和,max( 工资+奖金) as 最高工 资,avg( 工资+奖金) as 平均工资from zgda group by 职称, 性别
③Having 包含在查询结果中的组必须满足的条件, 即对分组的结果进行筛选, 去 掉不满足条件的分组,必须与Group by 同时使用
select 职称,count(*) as 职工人数from zgda group by 职称
select 职称,count(*) as 职工人数from zgda group by 职称having 职工数>=2
④如果有Group by 短语,而无order by 短语时,查询的结果默认以分组字段 的升序排列
⑤如果Where 和Having 同时使用时,先执行Where ,再执行Having
补充:在查询的过程当中使用了统计函数,并且查询结果可能有多个值,此时使 用group by 短语进行分组,在分组了以后,每组对应一条记录
(5) 集合的并运算( union )
A: 是将两个select 语句的查询结果合并成一个查询结果,默认情况下,合并的结 果删除重复的记录。用all 表示显示所有记录(包含重复记录)
B: 合并条件:
列数相同,并且对应字段的数据类型和宽度相同 对应字段的取值范围相同
合并格式:第一条完整的sql 语句union 第二条完整的sql 语句
例如:
sele * from zgda where 性别=”女” union sele * from zgda where 职称=”教授”
(6) 利用空值查询
注:查询空值时用: 字段名is null
select * from 订购单where 订购日期is null
查询不为空值时用: 字段名is not null
select * from 订购单where 订购日期is not null
(7) 保存查询结果
格式: select [all / distinct] 字段表达式[as 新字段名] [top n [percent] ] from 表名Group by 分类字段having 条件order by 排 序字段列表[asc] / [desc]
A: 输出到临时表中: into cursor 表名
执行完select 语句后,临时表仍然保持打开和活动状态,但为只读
一旦关闭临时表,查询结果则自动被删除
B: 输出到永久表中: into dbf / table [ 表名]
执行完select 语句后,此表依然处于打开和活动状态
这个表将永远保存在默认目录下
C: 输出到数组中: into array 数组名
这里的数组为二维数组,每行一条记录,每列对应查询结果的一列,数组中有
几行几列由查询结果中记录以及字段来确定
数组中可以存放n 个值,但他只属于一个内存变量
数组的下标是从1 开始的。
D: 输出到文本文件中: to file 文件名[additive]
扩展名为.txt, 无格式仅是纯文本
有additive 表示将查询结果追加到此文件内容的后面
3、数据定义
(1) 建立表(若建立数据库表,则必须事先建立或打开数据库)
格式:
create table 表名[free] ( 字段名1 类型(宽度,小数位数) [check 条件]
[error 字符串] [default 默认值] [NULL] [NOT NULL] [primary key]
[unique] ,⋯,⋯ [ ,foreign key 索引表达式tag 索引名references 父表名
[tag 父表的索引名]] )
注释:
free 说明此表为自由表。
create table 注册free( 姓名c(6), 性别c(2), 出生年月d)
类型只能用代表字母。
check 为字段指定有效性规则; error 表示出错时的提示信息
create table student( 姓名c(6), 性别c(2), 年龄i check 年龄>=10 error " 年龄超范围
")
Default 表示默认值
create table score( 学号c(10), 成绩n(7,2) default 40)
create table 教师( 姓名c(6), 性别c(2) default " 女", 基本工资n(8,2))
NULL 表示字段中允许取空值;NOTNULL 表示字段中不能取空值。
create table 职工( 编号c(5), 姓名c(6), 工资n(5,2) null default .null.)
primary key 表示建立主索引
unique 表示建立候选索引
foreign key 表示建立普通索引, 但不能单独使用, 在此之前必须先给父表建 立主索引或侯选索引, 建立普通索引的同时和父表建立永久性关系。若无[tag 父表 的索引名] 选项,则表示将关系建立在父表的主索引上。
不能建立唯一索引
(2) 修改表结构
A: 字段
修改字段名
alter table 表名rename [column] 原字段名to 新字段名
修改字段的宽度和类型
alter table 表名alter [column] 字段名类型(宽度,小数位数)
添加新字段
alter table 表名add [column] 字段名类型(宽度,小数位数)
删除字段名
alter table 表名drop [column] 字段名
B: 修改字段有效性
修改规则及提示信息
alter table 表名alter 字段名set check 条件[error 字符串]
修改字段的默认值
alter table 表名alter 字段名set default 默认值
删除规则及提示信息
alter table 表名alter 字段名drop check
删除字段的默认值
alter table 表名alter 字段名drop default
补充:添加新字段的同时设置有效性规则
C: 索引(表事先存在)
建立主索引
alter table 表名add primary key 索引表达式tag 索引名
删除主索引
alter table 表名drop primary key
建立侯选索引
alter table 表名add unique 索引表达式tag 索引名
删除侯选索引
alter table 表名drop unique tag 索引名
建立两表之间的永久关系(建立普通索引)
alter table 当前表(子表) add foreign key 索引表达式tag 索引名
references 父表[tag 父表的索引名]
删除两表之间的永久关系( 删除普通索引)
alter table 表名( 子表) drop foreign key tag 索引名
(3) 表的删除(物理删除)
A: 删除自由表: drop table 表名
B: 删除数据库表:
打开数据库
drop table 表名
4、操作功能
(1) 插入记录
A: 插入单条记录
insert into 表名(字段名1,字段名2,⋯) values ( 表达式1,表达式2,⋯)
注释:如果要向当前表所有字段中插入所有值,则第一部分可以省略
第二部分表达式的值必须与对应的字段类型相同
B: 将数组中的值插入到表中
insert into 表名from array 数组名
(2) 删除记录( 逻辑删除)
delete from 表名where 条件
(3) 有规律的修改记录或替换记录
update 表名set 要修改的字段名=用谁来修改where 条件
5、联接查询
(1) 简单联接查询
select 多表中字段名列表from 多表列表where 联接条件
基于多个表的查询,查询的结果可以出自多个表中
找出工资多于1230 元的职工号和他们所在的城市
Select 职工号, 城市from 职工, 仓库where ( 工资>1230) and ( 职工. 仓库号=仓库. 仓库号)
找出工作面积大于400 的仓库的职工号一级这些职工工作的城市
Select 职工号, 城市from 仓库, 职工where ( 面积>400) and ( 职工. 仓库号=仓库. 仓库号)
(2) 嵌套查询
select 字段列表from 表名where 条件或字段名关键字in(select 一个
字段名关键字from 表名where 条件)
例:
哪些城市至少有一个仓库的职工的工资为1250
Select 城市from 仓库where 仓库号in (select 仓库号from 职工where
工资=1250)
查询的结果来自一个表,而查询的条件却涉及到其他表
in 的前面必须写关键字段,子查询的查询结果只能有一个字段,在内容上必须 和in 前的一样,但它们却发属于两个表 子查询的查询结果做为主查询的一个查询条件,子查询应该是一条完整的sql 语句
在嵌套查询当中,子查询中不能再使用嵌套查询
(2) 自联接查询
select 字段列表from 表名别名where 条件
(3) 使用量词和谓词的查询
A: 使用量词查询
select 字段名列表from 表名where 字段表达式比较运算符[ANY / ALL / SOME] ( 子查询)
ANY 、ALL、SOME是量词
ANY和SOME在查询中如果子查询只要有任意一条记录能使结果为真,主查询便 显示相应的记录
ALL 要求子查询中的所有记录都必须使结果为真时,主查询才显示相应的记录
B: 使用谓词查询
select 字段名列表from 表名where [NOT] EXISTS ( 子查询)
EXISTS是谓词,用来查询在子查询中是否有结果返回,即存在或不存在记录。
他本身并没有任何运算或比较。
(4) 超联接查询(基于多表的查询)
A: 两表:
select from 表1 [inner / left / right /full ] join 表2 on 联接条件
联接条件在ON短语中给出,联接类型在FROM短语中给出
INNER JOIN 满足联接条件的记录才出现在查询结果中
LEFT JOIN 在查询结果中包含JOIN 左侧表中的所有记录,以及JOIN 右侧表中 匹配的记录
RIGHT JOIN 在查询结果中包含JOIN 右侧表中的所有记录,以及JOIN 左侧表 中匹配的记录
FULL JOIN 在查询结果中包含JOIN 两侧所有的匹配和不匹配记录
B: 三表
select 字段列表from 第一个表inner join 第二个表inner join
第三个表on 第三个表中关键字=第二个表中关键字on 第二个表中关键字= 第一个表中关键字