Oracle之SQL基础回顾

有了JAVA语言和JAVA程序,我们就可以run WEB服务器,让WEB服务器来访问数据库服务器,比如我们每天去网上购物,

流浪个人网页,甚至这个邮件,以及你的用户名和密码,实际上都是保存在数据库服务器中,那么常用的数据库像ORACLE

MYSQL,DB2,SQLServer,这些常用的几类数据库,那我们在学习JAVA之后,我们来给大家讲数据库,这里我们以ORACLE为例,

给大家讲ORACLE的安装,以及配置,还有他常用的一些管理,我们通过它这个之后呢,学习SQL和PL/SQL,来对数据库进行一些

操作,那首先我们要讲数据库的安装,讲之前我们也要看一下这个图,我们前面一阶段讲JAVASE的时候,知识框图,我们讲完JAVA

基础以后,就可以给大家讲ORACLE数据库,通过ORACLE数据库来学习SQL和PL/SQL,进而我们可以讲一门技术叫JDBC,JDBC是用JAVA

连接数据库的一门技术,有了JAVA应用程序了,有了数据库了,那么我们就可以实现通过JDBC对各种数据库的连接,更重要的是对

数据库的增删改查操作,那么我们这一节先这么讲,安装ORACLE数据库,ORACLE数据库的安装和配置,这样我们先来安装,安装的时间

也会稍微长一点,我们用间隙的时间给大家讲一下ORACLE,我们会给大家发两个文件,我们这里安装是ORACLE 10g,实际上13年已经出

12C了,这里我们没有必要装最新的,这里有两个压缩文件,大家可以从网站上来下载,或者你直接从ORACLE的官网来下载,一个叫数据库端,

一个叫客户端,这两个解压以后分别生成文件夹,我们当然要先安装服务端,然后再安客户端,服务端有一个setup,对于win7的用户要

格外注意啊我们要以管理员身份来运行,以免在安装的时候出现问题,有一些win7需要以兼容性来运行,以兼容性来运行,你如果

不知道是否需要合理调解的话,如果出现闪退了,在回来调这个问题,我们先带领大家安装ORACLE的服务端,无非就是一个水平分表,

分库,一个主从,简单介绍一下数据库,一类是关系型数据库,还有一类是非关系型数据库,关系型我们主要以ORACLE为主,然后MYSQL

为辅,非关系型我们以Redis为主,后面我们还会以SSDB为辅,有人建议我讲MongDB,基本上北京,全国有点大,北京这个软件行业,

一般软件公司也就分这三类

1. 第一类就是互联网行业,目前都知道互联网行业正是最火的时候,前两年一直到现在,今年也是属于最火的,比如电商,P2P,O2O,

互联网金融这是一个行业

2. 然后传统领域的行业,比如交通行业,气象行业,电信,银行,某一个领域的软件需求,这可能也是一个行业吧

3. 还有就是做产品的了,做医疗,做军工,做OA,企业管理系统,第三方基于某一个领域的需求


这三个行业其实都涉及过,我最开始08年工作的时候,我做一个小产品,做一个饲料行业的ERP,ERP的管理系统,这个是一个ERP,下面

涉及到一个什么啊,有财务模块,还有凭证模块,还有库存模块,还有员工的采集,然后供应商,销售,那个时候这个系统其实算

挺大的了,我以前可能就涉及库存以及财务,对于传统领域的软件行业呢,我以前在交通和气象都做过,主要是交通做的比较久,

做了3年多,将近4年的交通行业,后期从12年开始吧,基本都是互联网行业,但是没做过电商,比如O2O啊,互联网金融都做过,其实

大体上分这三种,无论哪一个行业都离不开数据库,那根据不同的需求,选择相应的数据库做存储,正常来讲互联网行业用的MYSQL会

比较多,因为免费不收费,然后自己去做类似的集群啊,或者用户量比较大,用的缓存比较多,比如Redis,很多公司可能关系型数据库

已经不太爱用了,可能核心的当然是DB2,或者是ORACLE,其实ORACLE还是目前最主流的一个数据库,然后另外大部分数据就放在

Redis缓存里,在这里简单描述一下关系型数据库的重要性,也就是ORACLE的强大也是大家有目共睹的,他的综合能力要比MYSQL

强的太多了,包括ORACLE 12C里,出了一个标准就是集群吗,简单的说一下


咱们继续往下看,数据库类型差不多就是关系型和非关系型,无论怎么样,最后数据总有一个数据落地,数据落地一帮也就叫入库,

也就是写在我们的磁盘上,无论怎么说吧,根据你实际生活中的场景,咱们实际应用的范围,你如果有一个好的数据库设计理念,

一个好的数据库设计的思路,其实这个也算是一个技术,数据库设计,这是很关键的,你们往往可以在很复杂的场景下,去规避

一些不可预见性的问题,其实数据库设计,一个好的架构设计师,一个好的程序员,他对数据库设计是非常看重的,可能你这个

产品也好,你这个平台也好,几十张表,一点也不复杂,然后上线之后也转的非常快,然后过一年两年之后呢,可能你们的需求

越来越多,如果说你对这个行业很了解,然后你也能预见到以后,我的什么样的需求能够产生什么样的变化,那你就可以在数据库

最开始设计的时候,建表的时候,你就能够留下来一些预留的设计模式,设计的时候你就应该考虑的很远,这样的话以后业务逻辑

加上来的话,其实这个并不是太影响你整个平台的性能的,以前我有朋友做电信,他是怎么做的呢,开始第一批程序员,可能是20,30个

程序员,然后经过一年到半年的开发,比如一年的开发,数据库设计的几十张表,一上线跑的非常的happy,性能都没有问题,然后过了

一段时间,这一拨人百分之八十都已经离职了,包括管架构的都已经离职了,剩下的50多张表对剩下的人,干脆就不熟悉,然后又来

一拨人,第二波人20,30个人,开始开发新功能,又有新业务了,这里面的50,60张表他都不敢碰,因为他怕影响以前的功能,也不太懂

之前的那张表,设计的考虑的也就少一点,那这个时候怎么办,有需求我就得从新加表,可能第二波人开发完之后,实现功能,上线跑了

以后,数据库变成100多张表了,然后再来第三波,第三波又是20,30个,百分之八十都已经离职了,然后数据库里已经变成200多张了,

反正就是第三波,一般以前的电信行业,都是外包出去的,现在可能不是这么做的了,数据库都设计烂了,就是越来越慢,最后怎么把办,

没办法了,重构,所以说一个问题是什么呢,就是最开始设计数据库的一个人,一定要是非常有经验,能预见以后的需求和扩展,

并且对于整个行业,非常了解,所以数据库设计在咱们的开发中,是非常非常重要的

今天咱们主要是了解一下,有些人可能不用ORACLE,那也没办法,首先我们要讲通用的,sql基础吗,然后讲一些ORACLE

里面一些特殊的函数,特殊的一些用法,今天讲的都比较基础,比较简单,首先我们看一下SQL的基础,这个我们刚开始

学的时候都应该已经有所了解了,他底层分四类:

1. 数据库操纵语言,DML,就是data manipulation language,这种数据操纵语言,除了select语句以外,这个怎么说呢,

SELECT没地方放了,所以就放在DML里了,只要数据库有了DML操作的话,咱们的ORALCE数据库就会产生undo,就是一个日志,

就会记录一个日志,然后只要是DML操作,就会产生lock的锁,一把锁,这是DML操作

2. 然后DDL,就是data definition language,create table啊,什么create index,create动画视图啊,create这个是很大

很大的,create里面的语法是非常非常多的,不可能说都记全了,你可以去帮助文档去看看,alter也是很多的,千奇百怪的,

其实数据库ORACLE是博大精深的,drop,truncate清空,简单来看你可能就看到这4个单词,其实里面的内容是相当多的,

3. 事务控制语言这个是相当简单,TCL,transaction control language,commit和rollback,还有savepoint,commit就是

提交呗,rollback就是回滚,savepoint就是创建一个保存点

4. 最后也是两个非常博大精深的语法吧,grant和revoke,这个东西就相当于赋权的,如果你接触过ORACLE的话,就是咱们

有一个scott用户,scott用户可能是没有view视图这个权限的,那怎么办啊,那你就的grant什么什么,把这个view 视图的权限

给这个scott,然后回收的时候就是revoke


基本上咱们这4种,然后继续往下看

咱们就是简单的复习一下SQL的基础了,SQL基础首先是数据类型了,当然这里指的是ORACLE,ORACLE里面肯定有这几种吧

1. 字符型

2. 数值型

3. 日期型

4. 大对象型


字符就char,varchar这两种,数值就是number,整数包括小数都可以,日期就是date,timestamp,时间戳,大对象就是clob,

和blob,一个是存储二进制的数据,还有一个是单字节的,这两种,也就是音频和视频,大体上有一个了解

这里的SQL基础我并不想讲太简单的内容,我们就回顾一下吧,在ORACLE里面可能最常见的就是这三个函数,一个是date,一个是char,

一个是number,这三个函数相互的去转换,我这里用的是PL/SQL Developer,我们就直接进入,我们就用scott用户吧,你可以选择SQL

Window,SQL Window模式,你要是不习惯可以选择Command Window,是一样的,也是可以写SQL的,注意从前到后,第一个,第二个,第三个

第一个它是什么意思啊,TO_DATE,TO_CHAR,TO_TIMESTAMP,我们来复习一下,第一个就是把字符串转成一个日期类型的,给他起个别名

AS_DAY,FROM DUAL就是一个虚表第一个查询的结果是这样的,第二个就是TO_CHAR,当前的日期就是今天SYSDATE,把一个日期类型的

数据转成一个字符串,就是TO_CHAR,还有一个第三种,就是把字符串根据这种模板,转成一个TIMSTAMP类型的,结果也是一个时间,

这个都很简单啊

后面还有两种,TO_CHAR就是把当前的时间戳的数据转成一个字符串,看到的就是这种形式,小数点后就是6位,

时间是20点57分07秒然后是ORACLE精确的6位,接下来就是TO_NUMBER,我把当前的时间,转成了字符串,然后里面有一个REPLACE,

相当于把里面的杠去掉了,最后变成这样的字符串,TO_CHAR,TO_DATE,TO_TIMESTAMP,还有TO_NUMBER,都可以结合的去使用,

这个在开发也是非常常用的,所以说我们顺带着复习一下

然后TO_CHAR他还有一种用法,这里面可以放一个参数,当前这个今天,今天是今年的第几个季度,三个月一个季度,

还有week,好像表示的是第几周,不过没关系,我们这里有一个: http://blog.csdn.net/delphi308/article/details/25654455

Oracle中TO_DATE TO_CHAR格式,有一个博客你可以去参考一下,它里面是可以去转日期的,TO_CHAR(SYSDATE,'MONTH')可以转成

月,当前是第几个月,TO_CHAR(SYSDATE,'Q')表示季度,TO_CHAR(SYSDATE,'IW')第几周用IW,这里可以表示周,表示第几周,然后

方便你去计算,TO_CHAR(SYSDATE,'YEAR')转成年,然后下面也有很多,TO_CHAR(salary,’$99,999.99’)转钱的格式,有兴趣你

可以自己看看这边文章,这就是最简单的了,这些都是SQL基础,有些是ORACLE里面的,MYSQL有些也和ORACLE也比较近了,都是

比较像了,我记得MYSQL5.0以下版本是没有dual这张表的,select * from dual,*是不行的,select 11 from dual,它是一张

虚拟的表,这有什么用呢,比如说,你要计算的时候, select sysdate() from dual,这张表其实是一张虚表,sysdate是一个函数,

mysql是一个函数,这样的话你就看到这个问题了,其实我要执行的sysdate,执行的结果呢放到一个位置,其实它是一张虚表吗,

咱们ORACLE就好办了,就可以这样去写,select 1+1 from dual,执行他就等于2了,他可以去计算吗,其实很多时候我们就用到了

dual这张表,它是非常好用的,我举一个例子吧,我随便找一个查询语句吧,要取得的内容就是表套的,子查询很深,我要动态的去

取值,然后join的时候简单的看一下就行了,最后我用的是一个固定的值,

SELECT COUNT(*) FROM table_name where parent_id = 'xxxxx'这个是一个子查询的结果,然后外面DECODE一个函数,

SELECT DECODE一个结果可能等于一个数,总之这个结果最后赋给一个DAUL,其实就是当做一个值去做,如果这个不懂,

到时我们看到merge语法的时候,ORACLE的一个合并,你就知道DUAL是做什么,怎么做的了

这里是我要讲的两个函数,decode函数只有ORACLE有的,咱们正常的SQL语法,不管是MYSQL,ORACLE,还是SQLServer,

只要是SQL语法,他都支持CASE表达式,case表达式没问题吧,你肯定用的都很多,经常用case去做判断,这肯定没问题,

DECODE是ORACLE专有的,他跟CASE比较像,只不过是一个简化,我们先运行一下,我现在查的是EMP表,EMP表咱们应该都有

印象吧,SCOTT用户里面的EMP表,select * from emp;其实很久没有用EMP表了,有14个数据的,我先做什么事啊,我去查询

EMP表的empno,就是部门编号,最后一行,如果这个编号如果是10的话,就是一个判断,如果编号等于10,与他相匹配的话,

输出部门1,如果部门编号与20相匹配,那就输出部门2,如果这个编号既不是10也不是20,那最后就输出一个部门3,他就是这样

一个逻辑,第一个值DEPNO作为一个动态的参数,我一共有14条记录,咱们举个例子,第一个值是SMITH,他的部门编号是20,

DEPNO就变成20了,他去判断10,一看不等,20肯定不等于10啊,那部门1就不输出了,那继续判断,跟20去判断,一看相等,

那我就用部门2去替代了,如果ALLEN等于30,和20不等,那就直接跳成部分3了,差不多就是这个意思,最后就输出了两个字段,

一个是DEPNO,CASE也差不多,CASE就不讲了,这个大家都知道,做开发的如果CASE都不知道,那就说不过去了,case when,

当depno=10的时候,then就输出一个部门1,然后继续when,depno=20的时候,then就去执行部门2,else剩下其他的情况,

我就输出部门3,然后就结束我们的CASE,他们两个的结果都是一样的,这个我们昨天说了,我们讲shell脚本的时候,shell脚本

里面的case,就是if else判断,跟SQL语法,存储过程什么的,比较像,还记得我们的if怎么写吗,if 空格 中括号[ -d表示一个

文件夹,如果这个条件满足的话,然后then输出一堆结果,然后还有else if,然后then,最后就是else,然后就是输出,

最后一个else是没哟then的,然后if是反过来写fi结束,shell还有印象吗,跟这个有点像,他都是一个东西假山给一个结果,

这个没有问题吧,这都很简单啊,在ORACLE里面,其实还有很多的函数,其实是很好用的,比如TRUNC,比如你们计算月份

ADD_MONTHS,还有MONTH_BETWEEN,还有LAST_DAY,REPLACE替换,SUBSTR,CONCAT,绝对值ABS,ROUND,就是这些函数其实很好用的,

可能有些是ORACLE专有的,有些是SQL专有的,比如TRUNC,CONCAT,还有SUBSTR,这几个不管是ORACLE,还是MYSQL,SQLServer,

好像都有这几个函数,给你发的一个函数大全,这里应该都有吧

分组就不用说了,分组的特性,分组组函数,sum,min,max,avg,count,分组特性就是group by....继续过滤having,

这几个小题很简单吧,查询每个部门的平均薪水之后显示部门平均薪水大于2000的部门编号和其平均薪水,然后这里

给你一个SQL,然后让你把汉子给标识出来,还有一个是查询部门的薪水和,再算出所有部门的平均薪水,这三个小题我做了

10分钟你把这三个做出来,这就是一个查询

剩下的就是基础,咱们这种集合联合,笛卡尔积交叉连接,等值非等值,内连接,外连接,左外右外,全连接,自连接,自然连接

这些都不用说了,都应该很简单,我们都学过,然后集合运算,如果是MSYQL有union和union all,然后取交集intersect,和

minus,MYSQL里也有,也就是都一样,union这个知道吧,union all这个应该都知道,intersect取交集取公共的部分,minus是

取差集,举个例子吧,有两张表,A表和B表,然后A表里面有张三和李四,B表里面有李四和王五,那就是我画两张表呗,第一张

就是A,这是张三,这是李四,B表里有2和3,这是李四,这是王五,那也就是说,有公共的部分都有李四,A表单独有个张三,B表 

单独有个王五,这个我就不操作了,太简单了,然后我select * from A,select * from B,就是我刚刚画的两张表,我想执行

取交集intersect,然后查询完了之后结果就是这样做的,select * from A intersect select * from B,他查询的结果就是

把李四查询出来了,就是一个李四,因为他们两张表的交集就是李四那一部分,如果你要执行minus,A表里面有张三和李四,

然后B表里面有李四和王五,A表如果在前面就以A表为主,B表如果在前面就以B表为主,他们两个结果集相减,差集,A减去B的

话,李四咱们就略了,李四就直接约了,剩的就是张三,因为是以我A表为主,反过来如果是B减A的话,那就是4和5减去3和4,

那就相当于把4约掉,结果集就是以B表为主,因为B在前面吗,结果就剩王五一个人了,就不考虑张三这个事了,很简单吧

子查询分两种,一种是非关联,还有一种是关联,非关联子查询你要知道这个概念,在这里我给个比较简单的概念,

就是主查询和子查询是相对独立的,那就叫做非关联自子查询,主查询和子查询是相对独立的,这个就是简单的再

复习一遍吧,那下面我写的肯定是关联子查询了,首先这两个结果集,先看一个吧,上面是非关联子查询,就是主查询

和子查询是独立的,为什么呢,就是子查询我自己是能运行,子查询我自己一点就能运行,这个是不是证明,子查询直接

能跑,就是跟你主查询不关联,咱两没有任何的关系,我这边一执行就是一个结果,A.DEPNO可能就等于10,那这个就是

非关联子查询,这很简单,关联子查询就是子查询自己一个人跑不起来,你一运行报错,就是有关联的,比如这个SQL就是

一个关联子查询,这什么意思啊,我想SELECT EMP这张表,然后我要查DEPTNO,然后要使用到EMP的DEPTNO,然后和另外的

一张表DEPT,部门的这张表进行关联,B.DEPTNO=A.DEPTNO,得到location这个结果,最终查出来的就是这个东西,非常简单

的一个关联子查询,就是对于关联和非关联子查询,再简单的复习一下,然后就是EXISTS和IN,EXISTS和IN再次确定一下,

是非常非常基础的问题了,非常初级的程序员可能会问的问题,EXISTS和IN有啥区别呢,EXISTS和IN比较的话,IN是做FULL

SCAN,就是做全表扫描,EXISTS是判断是否存在,非全表扫描,他们两个的区别就是,相当于啥啊,如果有100条数据,然后你要 

查的数据就在第五条的话,EXISTS的效率一定是高于IN的,为什么啊,因为IN是做FULL SCAN,因为100条记录都扫描完了之后,

然后获得判断把结果集人扔给你,这是IN,EXISTS查到第五条,就直接返回了,后面的95条就不查了,如果你的点比较低的话,

查的数据正好是在第100条呢,无论是IN还是EXISTS,都得查到最后一条,才能返回结果,所以有的时候说优化,我觉得是没所谓

的事情,查询属于领导的员工,我现在还是那这张表吧,就是咱们的EMP这张表,我们回顾里面的字段,这里面有两个字段是

想通的,一个是EMP_NO,还有MGR,还记得吧,这个是一个领导的关系,就是id员工编号,7369,SMITH的上级领导是7902,咱们找到

7902,7902还有上级领导是7566,再找到7566,7566JONES这个人也有一个领导7839,7839再看就是一个KING了,他的上级领导

就是null,就是空的了,也就是这个东西可以做自连接,可以形成一个TREE,就是树形结构的一张表,那我现在问题就来了,查询

属于领导的,大小领导都算,这什么意思呢,只要你这个人有领导的,那你就把员工列出来,怎么去写呢,你想一想是不是这么去写的

首先B.MGR=A.EMPNO是自己和自己关联了,就是A的EMPNO在B的MGR里面有,就是把EMP看成两种表吗,第一张表这么多,第二张表

以这个为主,第一个圆圈里面的编号,在MGR这一列,在MGR这里面有,是存在着的,如果EXISTS,直接就把领导的员工给列出来了,

属于领导的员工就这几个人

这个是不是很简单,然后还有一个查询哪个部门不存在员工的部门信息,那就是说我查询有一个部门,部门里面是没有

任何员工的,然后要查他的部门信息,那这个东西也应该很简单,select 1代表一个值,就是第40个部门里是没有任何的

员工的,你想一想咱们学SQL的时候,其实都是这样的,就是EMP表里,E.EMPTNO,这一块咱们把两张表列出来吧,

SELECT * FORM EMP,SELECT * FROM DEPT,两张表,也就是EMP表里的编号呢,就是10,20,30,但是我这个DEPT表里呢,

有一个40的编号,也就是40这个编号里面是没有任何员工的,那我刚才的问题就是,查询那个部门不存在员工的部门信息

你只要把40这个部门查出来就可以了,你看我是怎么写的,像这种肯定都需要关联子查询才能够解决吗,EMP表里面第一块首先

是DEPTNO跟第二张表里,也就是DEPT进行一个关联,这里面肯定是存在的,然后做一个非也就是NOT EXISTS,查询出来的就是最后

的一个40,就理解这个=事,很简单

咱们最后一个小基础,要注意的问题就是ROWNUM,在ORACLE里面其实用的还是挺多的,这个应该记得吧,我记得MYSQL里面是用LIMIT,

比如5到10,就这个很简单,ORACLE里面分页就的用ROWNUM,就是行号ROWNUM,然后你要注意ROWNUM的使用是有规范的,使用小于可以

查询结果,使用大于查询是没有任何结果的,就是ROWNUM使用的时候你不能使用大于号,使用大于号是没有结果的,使用别名的形式

才能进行查询,这样大于号才有结果,首先查询小于5的记录数,SELECT * FROM EMP这张表,无非我现在是想查询前4条ROWNUM记录,

就是要查询这前4条,怎么办呢,ROWNUM在ORACLE里是一个虚拟的列,行号,编号,查询ROWNUM小于5的,我就直接可以这样去用,他就会把

前四条给我查出来,就是7369到7566,如果用大于5,去查的时候那就啥也没有了,SELECT * FORM EMP WHERE ROWNUM > 5,你要用

大于的话你就必须得用一个,这里面说了,大于5的记录的话,你的使用别名了,这是ORACLE比较特殊的地方,大于5的数据,他的

用一个别名,就得用一个子查询,你的给他取一个别名RN,然后你得把这个当做一个结果集,当做一个视图,当做一个表A,

SELECT * FROM A WHERE 条件,加上RN这个字段他去大于5,这样才会有结果,这是ORACLE的ROWNUM的一个使用,薪水前三名,

你要是用大于等于3,你就得用内联视图,首先KING的薪水是最高的,SCOTT和FORD是2,3位,就是把内联视图查询出来,desc降序排序,

最高的薪水肯定在前面,然后再用ROWNUM进行小于等于,这个不用大于,小于的话就可以不用别名了,如果大于你得用这个别名了

还有最后一个分页,这个也简单啊,这里用一个between and 就搞定了,注意一件事情,between and是包含的,

有的比较初级的程序员,总是有一个疑问,有一个什么疑问呢,我想查一天的数据,举个例子,查询2016-02-18

我现在就有一个问题,让你查询今天的数据,今天一天的数据,你怎么去查啊,这个就是一个参数值吗,今天,

今天一个参数值,然后你得通过今天的时间去过滤掉这个参数值,今天一定是从0分0秒开始的,开始查,然后 

一定是大于等于这个结果,然后小于第二天的结果,你要查的那个值啊,举个例子啊,一定是这种条件才能

查询一天吗,大于等于今天,18号肯定有时分秒我就略了,从这个18号开始查,这边都满足我们的范围,并且

小于19号,就包括以后你做什么统计分析啊,做一些存储过程JOB的定时任务的时候,一个大于等于,一个小于

你不能用between and,你只能用大于等于和小于号,去做这种时间的限制,能理解我说的意思吧,相对来讲是比较

基础的,你肯定都写过存储过程,做过这种时间段的统计,他都是大于等于小于,简单的回顾一下SQL的基础,

都是非常基础的内容了,MERGE语法啊,递归函数啊,比如ORALCE的一些分析函数啊,over,partition,row_number,

cube,grouping,ORACLE特有的分析函数

猜你喜欢

转载自blog.csdn.net/Leon_Jinhai_Sun/article/details/89947701