数据库3:基于ORACLE的SQL基本操作

一、学习目标

-创建、更改和删除数据库、模式、基本表

-各类查询操作(单表查询,连接查询,嵌套查询和集合查询)

-更新操作(插入数据、修改数据、删除数据)

-创建视图、删除视图

-索引的设计、创建、使用和维护

-系统函数的使用方法

二、基本概念&语法语句

SQL概述

-SQL的综合统一:集数据定义语言(DDL),数据操纵语言(DML),数据控制语言(DCL)功能于一体。

-SQL基本语言

-SQL和数据库三级模式的对应


数据定义

ps:这边先写理论,最后我会整理一个全部要背的代码

-数据定义主要是模式定义、表定义、视图定义、索引定义

-SQL命名规则

首字母不许是:数字和$

不允许出现的:空格和特殊字符

长度:<=128

常见组成:字母、中文、数字、_、@、#、$

其他:不能使用SQL保留字、SQL不区分大小写

 -模式定义

由DBA创建或者由具有CREATE SCHEMA权限的人创建

模式实际上是一个命名空间

一个模式包含多个基本表,一个基本表一定属于某个模式

-定义表

定义基本表所属的模式有三个方法

01在表名中显示的给出模式名

02再创建模式语句中同时创建表

03设置所属的模式 SET search_path TO "schema_name"

-SQL数据类型:字符型、数值型、日期型

--CHAR类型,定长字符串

--VARCHAR, 变长字符串

--NUMBER(P.S)  P--有效数字的位数   S--为正数时表示从小数点到最低有效数字的位数,为负数时表示从最大有效数字到小数点的位数

--INTEGER 整数 FLOAT BINARY_DOUBLE BINARY_FLOAT 都是NUMBER的子类型

--DATE 日期

-索引的建立与修改

目的:加快查询速度

类型:B+树、Hash(散列)、顺序文件上的索引、位图索引

建立和自动建立:PRIMARYKEY & UNIQUE是自动建立 其他的都是DBA或者表的拥有者建立

维护和使用:都由DBMS自动完成
 

---数据定义

--定义模式

CREATE  SCHEMA schema_name AUTHORIZATION user_name

--定义表

CREATE TABLE table_name

(

        <列表> <数据类型和长度> [列级别完整性约束条件],

        <列表> <数据类型> [列级别完整性约束条件],

        .....

        [表级完整性约束条件]

);

--显示定义基本表所属模式

CREATE TABLE "schema_name".table_name 后面和创建表一样

--修改基本表(添加删除约束,添加删除列,更改原有列的类型)

-添加约束和删除约束

ALTER TABLE table_name ADD CONSTRAINT constriant_name FOREIGN KEY(sno)

REFERENCES anotherTable_name(cno)

ALTER TABLE table_name DROP CONSTRAINT constraint_name [CASCADE|RESTRICT]

-添加列和删除列

ALTER TABLE table_name ADD column_name NUMBER(9,2);

ALTER TABLE table_nameDROP column_name [CASCADE|RESTRICT]

-修改原有列的类型

ALTER TABLE table_name ALTER COLUMN col_name 新的数据类型

--删除表

DROP TABLE table_name [CASCADE|RESTRICT]

--定义索引

CREATE [UNIQUE][CLUSTER] INDEX index_name ON table_name(col_name ASC/DESC)

UNIQUE:假如有两个重复的值,只对一个值建立索引,而且不能插入重复值了

CLUSTER:聚簇索引

--修改索引

ALTER INDEX <old_index_name> RENAME TO<new_index_name>

--删除索引

DROP INDEX<index_name>

---删除

-删除模式

DROP SCHEMA schema_name <CASCADE|RESTRICT>

-删除表

DROP TABLE table_name 

-CASCADE:级联,可以理解为跟它有关系的一律删除

-RESTRICT:限制,如果有跟它有关系的,就拒绝该操作


数据查询(重点)

-基本结构

我把他分为五层 然后就按照每层可以写什么来整理了

--①

-ALL 是默认值表示全部

-DISTINCT 去掉重复的值,作用范围是所有目标列,所以只有当所有目标列都一样的时候才算是重复值,出现一次就可以啦,出现多次不对哦!

-<目标列表达式>

这个地方是分大小写的

单表不用带表名前缀,多表且重名的时候要加表名前缀

*代表查询所有列

表达式即为可以进行一些简单的运算 比如 2019-Sage或者直接是一个常量'BIRTH'

取个别名  'YEAR OF BIRTH' 2019-Sage

表达式前也可以有一些聚集函数

COUNT ([DISTINCT|ALL] col_name) // 跳过空值

COUNT(*) //对元组计数,不跳过空值

SUM ([DISTINCT|ALL] col_name)

AVG ([DISTINCT|ALL] col_name)

MAX ([DISTINCT|ALL] col_name)

MIN ([DISTINCT|ALL] col_name) --这几个的范围:没有GROUPBY就是全表范围,有就是组范围

LOWER (col_name) 全转化为小写

代码

-聚集函数

--②

FROM后面是需要查询的表名,一个就是单表查询,多个就是连接查询

FROM后可以给表起别名

FROM后可以又外连接查询(这个在下面连接查询概念有细说

FROM后可以有派生表 这个也是要取一个别名的 经常用于涉及聚集操作;对聚集结果再查询

-自身连接的时候要取别名,不自身连接想起也能起,就是没啥用

SELECT  FIRST.Cno, SECOND.Cpno

FROM  Course  FIRST, Course  SECOND

WHERE FIRST.Cpno = SECOND.Cno;

-外连接(可以看书上p101感觉还是比较形象)

FROM  Student  LEFT OUTER JOIN SC ON   (Student.Sno=SC.Sno);--Studen.Snot为主体

FROM  Student  RIGHT OUTER JOIN SC ON   (Student.Sno=SC.Sno);--SC.Sno为主体

FROM  Student  OUTER JOIN SC ON   (Student.Sno=SC.Sno);--两者都保留

-派生表例题(我感觉派生表查询和相关子查询之间可以互换)

找出每个学生超过他自己选修课程平均成绩的课程号。

SELECT Sno、Cno

FROM SC,(SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno)AS AVG_SC(AVG_SNO,AVG_GRADE)

WHERE SC.Sno=AVG_SNO And Grade>=AVG_GRADE;

练习:设有表book(类编号,图书名,出版社,价格),要求查询book表中大于该类图书价格平均值的图书名称。

--③

-满足条件的元组

 确定范围的必须小的值在前

字符匹配:%表示任意长度(可以为0哦);  _代表一个字符长度;[EACAPE '换码字符' ]

空值只能用is null/not null不可以用等于号!

运算符优先级:括号>AND>OR

-连接查询的连接字段就是列名称

代码

WHERE  Sage NOT BETWEEN 20 AND 23;

WHERE Sdept NOT IN ('IS','MA’,'CS' );

WHERE  Cname LIKE  'DB\_%i_ _' ESCAPE '\ ' ;

WHERE   Sdept= ' CS' OR Sdept= ' MA' OR Sdept= 'IS ';--可以换成IN

-嵌套查询,在where中又有新的子查询

        子查询不可以有ORDER BY哦,ORDER BY只能是作用在整张表的结果上

        相关子查询(重点):把子查询毙了,整个查询不能执行(官方:子查询的查询条件依赖于父查询

        不相关子查询:把子查询毙了,代码可以跑,就是不一定对(官方:子查询的查询条件不依赖于父查询)

        嵌套查询的查询条件:除了前面有的,还有ANY\ALL\EXISTS,不过只有内层查询返回单值的时候才能用比较运算符

        01 ANY\ALL 随便一个\全部

        02 EXISTS 这个我感觉超难

若内层查询结果 非空 ,则外层的 WHERE 子句返回真值
若内层查询结果 为空 ,则外层的 WHERE 子句返回假值
NOT EXISTS 相反

         用EXISTS/NOT EXISTS实现全称量词(全称和存在量词之间的转换关系)

 将非提到括号内,存在变成任意 

 两个非抵消 最后变成(任意x)P成立

代码

-相关子查询

找出每个学生超过他选修课平均成绩的课号(这个也可以用派生表来查)

SELECT Sno, Cno

FROM    SC  x

WHERE Grade >= (SELECT AVG(Grade)

         FROM  SC y

                            WHERE y.Sno=x.Sno);

发现没它的执行顺序其实是先外层拿一个,然后内层做一遍,如果符合,就把外层的留下

练习:设有表book(类编号,图书名,出版社,价格),要求查询book表中大于该类图书价格平均值的图书名称。

--EXISTS

查询所有选了一号课程的学生姓名

SELECT Sname

FROM Student

WHERE EXISTS(SELECT * FORM SC WHERE Sno=Student.Sno AND Cno=1);--这也是个相关子查询

--EXISTS 全称和存在

查询选修了全部课程的学生姓名

任意一门课的课号都能在sno中对应==不存在(存在一个课号 满足 该课号在sno中不存在)

SELECT sname

FROM student

WHERE NOT EXISTS  ( SELECT *

                            FROM Course

                            WHERE NOT EXISTS  (SELECT *

                                                              FROM SC

                                                              WHERE Sno= Student.Sno AND Cno= Course.Cno) )

还有一道例题我觉得一定要好好看看

-④GROUP BY 子句

要注意如果是针对于分组的条件筛选需要写在HAVING子句下

-HAVING与WHERE的不同

        作用对象不同 Having作用于组,选择满足条件的组;Where作用于表或视图,选择满足条件的元组

SELECT Sno

FROM SC

GROUP BY Sno

HAVING COUNT(*)>3; --这里作用在每一个SNO一样的组上,看这个组是不是满足加起来大于3

-查平均成绩大于90的,这里AVG的作用范围因为GROUP BY变成了组范围

SELECT Sno,AVG(Grade)

FROM SC

GROUP BY Sno

HAVING AVG(Grade)>=90;

-⑤ORDER BY子句

对最终结果排序用的

可以按照一个或者多个属性列排序

ASC是升序 DESC是降序

空值的处理ORACLE是缺省认为null是最大值,但是可以显示决定空值排前面还是后面NULLS FIRST/NULLS LAST

代码

-两个属性升降序要求不同

ORDER BY first_name ASC,last_name DESC;

-对于空值

SELECT country_id, city,state FROM locations ORDER BY state ASC NULLS LAST;

--连接查询

表现在From和Where两个子句中

首先分为等值和不等值,其次连接的部分必须是类型可比的

数据库具体的执行:嵌套循环法、排序合并法、索引连接法

-自然连接(与等值连接的区别在于有无相同的属性名和数据类型)

        公共属性合并只显示一个

-自身连接

        表和自身连接,必须起别名

-外连接

        普通连接只输出了符合条件的元组,但外连接可以输出不满足的

        左外连接、右外连接、全外连接

-多表连接

--查询之间的集合操作

交集INTERSECT、并集UNION、差集MINUS

要求:查询结果列得相同,对应项的数据也得相同

ps:UNION会自动去除重复,不过你可以用UNION ALL


数据更新

这部分基本上都是代码

--插入数据

-插入一个元组

INSERT INTO table_name(col1,col2,col3...) VALUES (' ',' ',' ',....)

INSERT INTO Student(Sno,Sname,Ssex,Sdept,Sage)VALUES ('201215128','陈冬','男','IS',18);

-插入一个查询结果(查询的列要和插入表的列一致哦)

INSERT INTO table_name(col1,col2,col3...) 子查询;

INSERT INTO table_name(col1,col2,col3...)

SELECT * FROM Student .......

--修改数据

   UPDATE table_name

   SET col_name=NEW [WHERE <条件>] --别忘了WHERE中是可以有子查询的!!     

--删除数据(删除的是元组

DELETE 

FROM table_name [WHERE<条件>]


空值处理

空值表示什么:不知道”或“不存在”或“无意义

空值的判断:IS NULLIS NOT NULL

空值的约束条件:NOT NULL 和  UNIQUE 约束的和 码不能取空

空值的算术运算:俩空值的运算结果是空

比较运算:UNKNOWN


视图处理

虚表:从视图和基本表而来,只存放定义不存放数据,在对视图查询时,按视图的定义从基本表中将数据查出。

--定义视图

先看下代码

--定义视图

CREATE VIEW table_name(col_name1,col_name2....)

AS <子查询>

[WITH CHECK OPTION];--对视图的操作要满足WHERE 后面的谓词条件

--比如

 CREATE VIEW IS_Student

        AS

        SELECT Sno, Sname, Sage

        FROM     Student

        WHERE  Sdept= 'IS';

WITH CHECK OPTION;--UPDATEINSERTDELETE操作时要满足Sdept= 'IS'

ps:一般SELECT 处不要用*

-col_name 必须有的情况

某个目标列是聚集函数或列表达式

多表连接时选出了几个同名列作为视图的字段

需要在视图中为某个列启用新的更合适的名字

-视图的种类:

        行列子集视图:单个表,且保留了主码

        基于多个基表的视图

        基于视图的视图:在view上又定义的view

        带表达式的视图:某一属性在原表中不存在而是派生出来的

        分组视图:带有聚集函数和GROUP BY

--查询视图

视图消解法:转换成等价的对表的查询,局限性:SUM\AVG\GROUP BY \MAX\MIN这种没办法生成正确的查询(行列子集视图可以正确转换)

物化视图法:先把视图实体化成一个表,就相当于在表上查询了(ORACLE就是这么干的)

--更新视图(可以唯一有意义的转换成对相应基本表的更新)

语法上来讲和更新表一样,但是有的视图是无法更新的(根上面不能用消解法的一样)具体如下

 另外不允许更新的视图上定义的视图也不许更新

--定义视图并查询和基于派生表查询的区别

视图一旦定义其定义将永远存在于数据字典中,之后的查询谁有可以直接引用,但是派生表只是临时定义的,语句执行之后被删除

-什么时候定义为表?什么时候定义为视图?

表的内容不会变,视图的内容随着基本表的变化而变化

代码

--视图种类举例:分组视图

CREATE VIEW S_G(Sno,Gavg)

AS

SELECT Sno,AVG(Grade)

FROM SC

GROUP BY Sno;

--删除视图

DROP VIEW view_name [CASCADE CONSTRAINTS];--如果视图上还导出了视图就要级联删除了

--查询视图根查询表没什么大区别

--更新视图 和更新表一样


视图的作用

§ 视图能够简化用户的操作
§ 视图使用户能以多种角度看待同一数据
§ 视图对重构数据库提供了一定程度的逻辑独立性
§ 视图能够对机密数据提供安全保护
§ 适当的利用视图可以更清晰的表达查询

猜你喜欢

转载自blog.csdn.net/karonneveralone/article/details/122326889