您的位置:首页 > 数据库 > Oracle

oracle 平时记录

2016-06-24 15:13 423 查看

oracle中的exists 和not exists 用法详解

有两个简单例子,以说明 “exists”和“in”的效率问题
1) select * from T1 whereexists(select 1 from T2 where T1.a=T2.a) ;
T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高。
2) select * from T1 where T1.a in (selectT2.a from T2) ;
T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高。
exists
用法:
请注意 1)句中的有颜色字体的部分,理解其含义;
其中“select 1 from T2 where T1.a=T2.a”
相当于一个关联表查询,相当于
“select 1 from T1,T2     where T1.a=T2.a”
但是,如果你当当执行 1) 句括号里的语句,是会报语法错误的,这也是使用exists需要注意的地方。
“exists(xxx)”就表示括号里的语句能不能查出记录,它要查的记录是否存在。
因此“select1”这里的 “1”其实是无关紧要的,换成“*”也没问题,它只在乎括号里的数据能不能查找出来,是否存在这样的记录,如果存在,这 1) 句的where 条件成立。
 
in 的用法:
继续引用上面的例子
“2) select * from T1 whereT1.a in (select T2.a from T2) ”
这里的“in”后面括号里的语句搜索出来的字段的内容一定要相对应,一般来说,T1和T2这两个表的a字段表达的意义应该是一样的,否则这样查没什么意义。
打个比方:T1,T2表都有一个字段,表示工单号,但是T1表示工单号的字段名叫“ticketid”,T2则为“id”,但是其表达的意义是一样的,而且数据格式也是一样的。这时,用 2)的写法就可以这样:
“select * from T1 whereT1.ticketid in (select T2.id from T2) ”
Select name from employeewhere name not in (select name from student);
Select name from employeewhere not exists (select name from student);
第一句SQL语句的执行效率不如第二句。
通过使用EXISTS,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因

Union  UnionAll用法

UNION 指令的目的是将两个 SQL
语句的结果合并起来,可以查看你要的查询结果.
例如:
SELECT Date FROM Store_Information

UNION

SELECT Date FROM Internet_Sales

注意:union用法中,两个select语句的字段类型匹配,而且字段个数要相同,如上面的例子,在实际的软件开发过程,会遇到更复杂的情况,具体请看下面的例子
select  '1' astype,FL_ID,FL_CODE,FL_CNAME,FLDA.FL_PARENTID from FLDA

WHERE ZT_ID=2006030002

union 

select  '2' as type,XM_ID,XM_CODE ,XM_CNAME ,FL_ID from XMDA

where exists (select * from (select  FL_ID from FLDA WHEREZT_ID=2006030002 ) a where XMDA.fl_id=a.fl_id)

order by type,FL_PARENTID ,FL_ID
这个句子的意思是将两个sql语句union查询出来,查询的条件就是看XMDA表中的FL_ID是否和主表FLDA里的FL_ID值相匹配,(也就是存在).
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。
在查询中会遇到 UNION ALL,它的用法和union一样,只不过union含有distinct的功能,它会把两张表了重复的记录去掉,而unionall不会,所以从效率上,union all 会高一点,但在实际中用到的并不是很多.
表头会用第一个连接块的字段。。。。。。。。。。
而UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
  从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL,如下:
尽量使用union all,因为union需要进行排序,去除重复记录,效率低。

Oracle
中 decode
函数用法

含义解释:
decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)

该函数的含义如下:

IF 条件=值1 THEN

    RETURN(翻译值1)

ELSIF 条件=值2 THEN

    RETURN(翻译值2)

    ......

ELSIF 条件=值n THEN

    RETURN(翻译值n)

ELSE

    RETURN(缺省值)

END IF
decode(字段或字段的运算,值1,值2,值3)

       这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3

当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多

使用方法:
1、比较大小
select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值

sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1

例如:

变量1=10,变量2=20

则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。

2、此函数用在SQL语句中,功能介绍如下:

Decode函数与一系列嵌套的 IF-THEN-ELSE语句相似。base_exp与compare1,compare2等等依次进行比较。如果base_exp和 第i 个compare项匹配,就返回第i 个对应的value 。如果base_exp与任何的compare值都不匹配,则返回default。每个compare值顺次求值,如果发现一个匹配,则剩下的compare值(如果还有的话)就都不再求值。一个为NULL的base_exp被认为和NULL compare值等价。如果需要的话,每一个compare值都被转换成和第一个compare
值相同的数据类型,这个数据类型也是返回值的类型。

Decode函数在实际开发中非常的有用

结合Lpad函数,如何使主键的值自动加1并在前面补0
select LPAD(decode(count(记录编号),0,1,max(to_number(记录编号)+1)),14,'0') 记录编号 fromtetdmis

eg:

select decode(dir,1,0,1) from a1_interval

dir 的值是1变为0,是0则变为1

比如我要查询某班男生和女生的数量分别是多少?

通常我们这么写:

select count(*) from 表 where 性别 = 男;

select count(*) from 表 where 性别 = 女;

要想显示到一起还要union一下,太麻烦了

用decode呢,只需要一句话

select decode(性别,男,1,0),decode(性别,女,1,0) from 表

 

 

3,order by对字符列进行特定的排序

大家还可以在Order by中使用Decode。

例:表table_subject,有subject_name列。要求按照:语、数、外的顺序进行排序。这时,就可以非常轻松的使用Decode完成要求了。

select * from table_subject order by decode(subject_name, '语文', 1, '数学', 2, , '外语',3)

 

instr函数(oracle
用instr 来代替 like)

对于instr函数,我们经常这样使用:从一个字符串中查找指定子串的位置。例如:

SQL>select instr('oracle','or') position from dual;

POSITION

----------

       1

从字符串'oracle'的第一个位置开始,向后查找第一个出现子串'or'出现的位置。

其实instr共有4个参数,格式为“instr(string,substring, startposition,
occurrence)”。可实现子串的如下搜索:

1.从指定位置开始搜索子串

2.指定搜索第几次出现的子串的位置

3.从后向前搜索

--1.从第3个字符开始搜索

SQL>select instr('oracleor','or', 3) position from dual;

POSITION

----------

       7

--2.从第1个字符开始,搜索第2次出现子串的位置

SQL>select instr('oracleor','or', 1, 2) position from dual;

POSITION

----------

       7

--3.从倒数第1个字符开始,搜索第1次出现子串的位置

SQL>select instr('oracleor','or', -1, 1) position from dual;

POSITION

----------

       7

--3.从倒数第1个字符开始,搜索第2次出现子串的位置

SQL>select instr('oracleor','or', -1, 2) position from dual;

POSITION

----------

       1

 

oracle用instr代替like

 

表中将近有100万数据,很多时候,我们要进行字符串匹配,在SQL语句中,我们通常使用like来达到我们搜索的目标。但经过实际测试发现,like的效率与instr函数差别相当大。下面是一些测试结果:

SQL>set timing on

SQL> select count(*) from t where instr(title,’oracle’)>0;

COUNT(*)

———-

5478

Elapsed:00:00:11.04

SQL> select count(*) from t where title like ‘%oracle%’;

COUNT(*)

———-

5478

Elapsed:00:00:31.47

SQL> select count(*) from t where instr(title,’oracle’)=0;

COUNT(*)

———-

994530

Elapsed:00:00:11.31

SQL> select count(*) from t where title not like ‘%oracle%’;

COUNT(*)

———-

994530

注:

instr(title,'oracle’)>0相当于like

instr(title,'oracle’)=0相当于notlike

over (partition by
)用法

     select
*
          from
(select a.*,
row_number()
over(partition
by a.task_id
order by
a.rtime
desc) rn
                  from
t_data a)b
         where
rn = 1

分页

select *
from  ( select
rownum rn,t.*
from t_data
t where rownum<=40)
where  rn>20
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: