Oracle之SQL高级使用

就是一些常见的解决方案,问一些简单的SQL,做一些比较老的东西,自己上网要搜一搜,可能问的人数据库不咋地,很多基础

要考自己找一些时间,自己看一看,真正有水平的问的还是设计的问题,怎么去解决大数据,水平分表分库,采用什么策略,

包括查询的时候采用多线程并发的去访问,这样节省性能,主要是节省时间,本来3个DAO要执行3秒,3个DAO调用3个线程去执行,

只要我内存足够,以内存的空间换查询的时间,3个并行也许就是1秒钟就执行完毕的事,这个都是提升效率的,很多问题都是

根据实际情况自己分析解决的,分区的数据如果排序怎么办,这个东西有很多解决办法,是一个区里面要排上一个序,还是跨分区

都排序,总体都排序,如果整体都排序的话,那你可以怎么办,你可以插入的时候来一个时间戳啊,id通过时间戳整体去排序,

一个分区一个分区的查,一个分区比如500万条数据,建立一个索引,索引的前一半时间戳,我们可以按照时间戳的大小,查完这个

分区之后,再查另外一个分区,分区的时候你要指定这个P1分区,P2分区,P1这里头所有的数,说白了就是P1里面是1-100,那他的ID

最大值100,那P2的分区是101-200,第三个分区是从201开始一直到300,整体来说就直接有个顺序了,方案太多了,某个业务的一个

时间,顺序是被打乱的,做法很多,利用插入的时候,做一个顺序,在插入数据的时候有没有一个规则,1一个分区里面有一个

2010-2-18,然后第二个分区里面还有一个201-2-18,你就相当于整个分区都要进行排序,那不如你插入数据的时候给你一个number,

做一个排序,我觉得是这样比较好,一般我们可能都是这么去做的,你想一想,没有其他的方案,要不你就用这一个字段查,

你想排序就建分区索引,然后去做,要不然你就在数据库入库的时候,定义一个规则,去排序,你要单独从SQL的角度来讲,

其实很多事情都是解决不了的,我个人还是从数据库设计能不能加一个额外的字段,或者加一个关系表,然后把所有的数据直接塞到

关系表里,这个以后再说吧,关于设计的事

咱们ORACLE里面提供了两种方式,create table,<new table>这是一个新的table, as select * from 要求目标表不存在,

因为在插入的时候会自动插入时会自动创建表,就是咱们create table,起个名字new_table,as seelct * from table where=..

这是可以的,举个例子,这是ORACLE的写法,现在create table,然后MYEMP,我这边就相当于创建一个table,然后as select *

from emp,CREATE TABLE MYEMP AS SELECT * FROM EMP WHERE EMP = 10,还可以加where条件,我把这个SQL写完了,MYEMP

已经存在了我把它DROP掉

然后执行完语句以后就多了一个MYEMP这张表,咱们点开看一下,里面就三条数据,这是ORALCE特殊的语法,类似咱们的

select into,只不过他这里是这么去写的,create table MYEMP,这个table是不存在的,as后面是你要往table里面要

加的数据,是可以加条件的,还可以去加join,几张表,都去做都行,很简单
还有一个是insert into table2(f1,f2,...) select v1,v2,... from table1,然后table2这张表必须得存在,这什么意思呢,

我想在已经存在的表tabl2里存在的列,每个列里面对应上,这个就没啥可说的了,只不过第一种方式是ORACLE支持的,create table 

是ORACLE特有的语法,MYSQL不能这么去做吧

接下来看这个,MERGE,MERGE这个语法也很简单吧,这什么意思呢,merge在MYSQL里面有吗,这个我不清楚,

MYSQL里面没有的,ORACLE里面有的,MERGE INTO这是固定的,他有一张表A,这是根表A产生的关联字段,我可以去进行一个

表的关联,如果匹配的话我做什么事,如果不匹配我做什么事

我现在直接create table,建立一张表,我看我这里有没有已经有了的表,我这里有个列子,写的话要写半个小时,

这是ORACLE特有的语法,现在我就想创建一个表,这个表就叫产品表PRODUCTS,产品表有几个字段,首先有一个ID,

它是Integer的,有一个Sequence Number,可能是一个序号,有一个PRODUCT NAME,就是产品名称,还有一个相当于型号,

CATEGORY,大体上就是这4个字段,然后把这个表创建起来,加入一些数据,现在我们select * from PRODUCT这张表

这张表就是这个结构,首先ID是不重复的,首先就是产品ID,序号就是这样的,然后每一个产品的名称在这儿呢,然后每一个产品的类型

就是定义一个产品表,然后我现在要做的事情是什么啊,MERGE的用法是什么意思呢,在这里举个例子,他可以合并,首先我写MERGE INTO

PRODUCTS这张表,然后取个名字叫a,起个别名叫a,然后我在这里可以使用一个语法叫做using,他这个是固定的语法,你看我这个,

MERGE INTO PRODUCTS表,using 这里是与A表产生关联的字段,看这个是什么意思,就是select 1717,你看这个就是我们刚才讲的

DUAL,他单独可以运行的,返回的就是这个结果了

就是1717的数值放到这儿了,给他去一个别名叫做PRODUCT_ID,给002取个别名叫req_no,from dual,这个查询结果集

就是一个内联视图,你查询出来的一张表吗,就是一行两列的一张表,第一列ID是1717,第二列是002,就是product_id,

req_no这两列要与PRODUCTS表产生关联,产生关联的关联条件呢,在下面就是on,a.product_id,就是products表的id

要和b表的products表关联,也就是我们刚才一行两列的这张表,我们称之为b表,就是a表和b表进行关联,又加一个and

条件,a.req_no=b.req_no,这就是一个on条件,你可以理解为b就是单独的一张表,然后a是单独的一张表,他们两个进行join,

然后条件是什么,join的条件是什么,这是我新加入的字段1717,肯定是存在的,但是002是不存在的,因为他们两个是and条件,

我1717这一行的req_no值是001,如果说匹配的话,匹配上的话我做什么事,那就mathed,then做什么,我就做更新操作,如果

not mathed,我就尽心insert操作,说白了一个就是更新一个新增,举个最简单的列子,如果表里有三条数据,这三条数据id等于

1,2,3,你还有一个动作想往里去插入数据,插入数据的时候比如说插入数据的额id是3,那么3在这条数据里已经存在了,那么已经

存在的时候就应该找到3进行update,因为3这条记录已经存在,如果这张要插入的数据是4的话,他一看这个4不在我这张表里,

这张表的id只有1,2,3,就直接插入,就是判断这个数据在不在表里,如果在这张表里就更新,如果不在就直接插入,按照我们JAVA的

逻辑来讲,首相通过ID看能不能取到这条数据,如果取到了我就update更新,如果没取到,我就直接insert,总之得有一个先查询的过程,

那么MERGE语句就是省略了这一块了,他直接就可以做到这个事,如果匹配上了我就直接update,没匹配我就直接更新,更新这个

PRODUCT_ID,更新这个REQ_NO,更新PRODUCT_NAME,更新category,把我传过来的数据直接更新一下,你看我这个SQL执行完了的结果,

首先我们这个表里一共是有6条数据,就一个1717,现在我执行一下这个,执行这个MERGE语法,然后commit直接提交了,

然后咱们在SELECT一下

那你会看一下它会多一个1717,002这个新产品,如果我再001,这里写进行更新了,然后写更新的category,

其实你发现这个时候1717,001这个时候在第5条已经重复了,那就是我在更新的时候要把PRODUCT_NAME,

和CATEGORY这个字段,这两个字段进行更新,提交,再次查询,MERGE就是这个用法

因为很简单吗,这个东西是很简单的,我们看最后一个,最后一个更简单,递归查询,,MYSQL里面有递归查询吗,

你们肯定会遇到一些问题,递归查询是start with,connector by prior,有没有的话我们讲一下吧

还是拿EMP表举例,EMP表里呢肯定有很多上级和下级的关系,它是一棵树,这棵树最顶上叫KING,因为他是最高的节点,

他下面有一些员工,比如有SCOTT,SCOTT下面也有员工,然后还有其他的,可能就是一棵树呗,那分层查询无非是要查询

某一棵树,可以向上去查,也可以向下去查,怎么查都行,看你这个语法怎么去写,这个语法就是这样的,首先是

SELECT * FROM 一张表EMP,如果有where条件就可以直接在这里加where条件了,然后你是一个条件也好,两个条件也好,

OR或者也好,你都可以在这里加条件,然后条件写完了以后就可以加这个,加这个固定的写法叫start with,开始于,

然后呢,开始于这个字段一定是,相当于一棵树的id和pid的关系,id表示当前ID,比如1,id等于1是长沙,2是北京,

假如2的父节点是1,这个可能叫pid,北京是一个子节点,长春是一个父节点,这棵树挂起来的话,长春下一级是北京,

因为pid和id是有关联的,所以你做分层查询的时候,一定是这两个字段,对应的是EMPNO和MGR,这两个字段是有对应关系的,

上下级关系,子节点相当于ID,MGR是父节点是PID,就这个意思,START WITH一定是有区别的,就是你要从哪个节点开始查,

你看我现在是从7369开始查,7269是谁啊,是SMITH,从这个节点开始查,那SMITH肯定是一个小人物了,不是领导,就是一个

普通员工,然后我查完这个根之后,下面是PRIOR BY,这个写法是固定的,MGR=EMPNO这块写法不是固定的,这是两个字段,

第一个是MGR,相当于PID,然后等于ID,然后ID是什么EMPNO,这个写法是固定的,id和pid,只不过PID在前面,或者有些时候

是ID在前面,或者PID=ID,这个是有区别的,我们先看这个结果查询的是什么吧,你会发现我执行完了之后

你看返回的是什么啊,就是从SMITH开始,然后找到SMITH的上级领导,然后是FORD,FORD的领导是7566,找到JONES,

JONES的领导是7839,也就是KING,这个就是把我一棵树的分支,查出来了,那这种查法就是从下至上查的,从SMITH

开始一级一级往上查的,一直插到KING结束了,那你说你要记住一个问题,如果PARENT_ID,就是pid,如果pid在前,

咱们的ID在后,这样的话就属于向上查询,如果我要把这个换个位置呢,EMPNO=MGR,这个就属于向下查询了

现在我们的这个结果就相当于我们的ID在前,就相当于他们两个调过来了,如果ID在前,然后PID在后,

那这块就是向下查询,你可以理解下,这个东西什么意思呢,往下查询的就是比较根的节点,比如我随便拿出一个JONES,

这个节点是多少,或者拿KING吧,7839,以7839为开始,肯定查出来的是14条记录

如果我以JONES查呢,咱们看一下JONES那人,JONES肯定有7566的孩子

向下查询,7566这个节点,就在这儿,JONES他有一个下级就是SCOTT,7788的下一个节点是7876,然后7876就没有下级了,

然后你看7566,就是SCOTT,他这边还有孩子,他有一个SCOTT,SCOTT下面还有一个孩子节点,7788是CLERK,7566,SCOTT

还有一个分支,可能是这样,总之从这个节点往下查询,就是你要考虑谁在前,谁在后,这个要稍微记一下,这个就是简单的SQL

查询,我在这里写了CONNECT BY,然后父节点=子节点是往上查询,PID在前,如果反之呢就子节点在前,父节点在后,向下查询,

而且还可以加WHERE条件限制,也可以指定多个节点查询,而且还可以指定ORDER排序,比如我现在就像查两个节点,刚刚我们查的

是7369,7369是谁啊,我现在要向上查询一下,是MGR=EMPNO,你看我到这个结果呢,从SMITH一直到上级都查出来

看看7934,7934应该也是一个最小的节点,就是两棵树,AND不行,是OR,或者吗,查两条数

这回你看到了,SMITH有这么多,这边是7934的上级,7934的上级是CLERK,我单独去查一个7934,看是不是一个效果

就是这三条数据就是一棵树,然后两个条件一起去查,然后还可以进行过滤,然后EMPNO不等于7839,把KING这个人刨除了,

这个都是可以的

还可以进行ORDER BY SAL DESC,这个都是可以的,可以一起去查询

按照这个薪水给我排序,这个应该是没问题吧,这个就是分级查询

猜你喜欢

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