常用的一些sql

-- 列操作
-- 增加和修改列不需要加关键字COLUMN
-- 删除单列的话,一定要加COLUMN,删除多列的时候,不能加COLUMN关键字

-- 增加一列
alter table emp4 add test varchar2(10);
-- 修改一列
alter table emp4 modify test varchar2(20);
-- 删除一列
alter table emp4 drop column test;
-- 增加多列
alter table emp4 add (test varchar2(10),test2 number);
-- 修改多列
alter table emp4 modify (test varchar2(20),test2 varchar2(20));
-- 删除多列
alter table emp4 drop (test,test2);
--在sqlplus中执行sql脚本,下面两种方式都可以
START file_name
@file_name


--判断表是否存在,如果存在则删除
declare
      num   number;
begin
      select count(1) into num from all_tables where TABLE_NAME = 'EMP' and OWNER='SCOTT';
      if   num=1   then
          execute immediate 'drop table EMP';
      end   if;
end;
/
--创建表
CREATE TABLE EMP
       (EMPNO NUMBER(4) NOT NULL,
        ENAME VARCHAR2(10),
        JOB VARCHAR2(9),
        MGR NUMBER(4),
        HIREDATE DATE,
        SAL NUMBER(7, 2),
        COMM NUMBER(7, 2),
        DEPTNO NUMBER(2));
可以将上述存储过程加载到每一个create table前面。

--ORACLE 判断序列是否存在,如果存在就删除

declare
 V_NUM number;

BEGIN
  ----多次删除时,每次都将v_num设置成为0
    V_NUM := 0;
    ----判断序列 seq_name_1 是否存在(区分大小写)
    select count(0) into V_NUM from user_sequences where sequence_name = 'SEQ_BUSINESS_PROCESS_INDEX_ID';
    ----如果存在立即删除
    if V_NUM > 0 then
    execute immediate 'DROP SEQUENCE  SEQ_BUSINESS_PROCESS_INDEX_ID';
    end if;
END;
-- 两个时间相隔的分钟数

select ceid((to_date('2016-07-21 12:12:12','yyyy-mm-dd hh24:mi:ss') - to_date('2016-07-20 11:11:11','yyyy-mm-dd hh24:mi:ss'))*24*60) from dual;


-- 时间转换

select sysdate,to_char(sysdate,'yyyy/mm/dd HH24:MI:SS') from dual;


-- 当前时间加十个月

select sysdate,add_months(sysdate,12) from dual;


-- 当前时间的下一个周六,1 表示下个周日,2表示下个周一
select next_day(sysdate,7) from dual;

-- 两个时间相隔的天数、月、分、秒
select 
    extract(day from b-a) day,
    extract(hour from b-a) hour,
    extract(minute from b-a) minute,
    extract(second from b-a) second
from (
     select to_timestamp('2018-5-1 8:8:8','yyyy-mm-dd HH24:MI:SS') a,
            to_timestamp('2019-5-2 9:9:9','yyyy-mm-dd HH24:MI:SS') b
     from dual        
     );


-- 当月的第一天以及最后一天对应的日期
select  to_char((last_day(to_date(to_char(sysdate,'mm')-1,'mm'))+1), 'yyyy-mm-dd')  as firstday,
        to_char(last_day(sysdate),'yyyy-mm-dd')  as lastday
from dual;    
Oracle中row_number()、rank()、dense_rank() 的区别
row_number的用途非常广泛,排序最好用它,它会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号。

rank函数用于返回结果集的分区内每行的排名,行的排名是相关行之前的排名数加一。简单来说rank函数就是对查询出来的记录进行排名,与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,如果使用rank函数来生成序号,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,可以理解为根据当前的记录数生成序号,后面的记录依此类推。

dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第三名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名


--row_number() 顺序排序
select name,course,row_number() over(partition by course order by score desc) rank from student;


--rank() 跳跃排序,如果有两个第一级别时,接下来是第三级别
select name,course,rank() over(partition by course order by score desc) rank from student;


--dense_rank() 连续排序,如果有两个第一级别时,接下来是第二级别 
select name,course,dense_rank() over(partition by course order by score desc) rank from student;


--每门课程第一名只取一个: 
select * from (select name,course,row_number() over(partition by course order by score desc) rank from student) where rank=1;
--每门课程第一名取所有: 
select * from (select name,course,dense_rank() over(partition by course order by score desc) rank from student) where rank=1;
--每门课程第一名取所有:
select * from (select name,course,rank() over(partition by course order by score desc) rank from student) where rank=1;

--  树形结构

-- 父节点向下查找
select level,a.*
from t a
start with  a.id = ''
connect by nocycle prior a.id = a.p_id ;


-- 父节点向下查找 (不包括父节点)
select level,a.*
from t a
start with  a.p_id = ''
connect by nocycle prior a.id = a.p_id ;    


-- 子节点向上查找所有父节点
select level,a.*
from t a
start with  a.id = ''
connect by nocycle prior a.p_id = a.id ;    

lpad   与   rpad 函数:

-- 先看例子:

select
lpad('1234',2) from dual; -- 12 select lpad('1234',5,'0') from dual; -- 01234 select rpad('1234',2,'0') from dual; -- 12 select rpad('1234',5,'0') from dual; -- 12340

中间的参数表示最终结果的长度,然后就是初始字符和是否 在左还是右 补充的问题了。

instr 函数

instr( string1, string2 [, start_position [, nth_appearance ] ] )   /   instr(源字符串, 目标字符串, 起始位置, 匹配序号)

select substr('999999'+100000,-5,5) from dual; 

REGEXP_SUBSTR函数(字符串转多行)
在oracle中,使用一条语句实现将'17,20,23'拆分成'17','20','23'的集合。

REGEXP_SUBSTR函数格式如下:
function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier)
__srcstr :需要进行正则处理的字符串
__pattern :进行匹配的正则表达式
__position :起始位置,从第几个字符开始正则表达式匹配(默认为1)
__occurrence :标识第几个匹配组,默认为1
__modifier :模式('i'不区分大小写进行检索;'c'区分大小写进行检索。默认为'c'。)

-- 1、查询使用正则分割后的第一个值,也就是17
SELECT REGEXP_SUBSTR('17,20,23','[^,]+',1,1,'i') AS STR FROM DUAL;  

-- 2、查询使用正则分割后的最后一个值,也就是23
SELECT REGEXP_SUBSTR('17,20,23','[^,]+',1,3,'i') AS STR FROM DUAL;  

-- 3、获取一个多个数值的列,从而能够让结果以多行的形式展示出来
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <=7;  

-- 4、将上面REGEXP_SUBSTR的occurrence关联
SELECT NVL(REGEXP_SUBSTR('17,20,23', '[^,]+', 1, LEVEL, 'i'), 'NULLL') AS STR  
  FROM DUAL  
CONNECT BY LEVEL <= 7;  

--  5、优化上面的SQL语句,让生成的行的数量符合实际情况
SELECT REGEXP_SUBSTR('17,20,23', '[^,]+', 1, LEVEL, 'i') AS STR  
  FROM DUAL  
CONNECT BY LEVEL <=  
           LENGTH('17,20,23') - LENGTH(REGEXP_REPLACE('17,20,23', ',', ''))+1;  

wm_concat 函数  (多行字符串转一行)

select  t.id,to_char(wm_concat(t.name))  from t  group by t.id;

 需要注意的是,WMSYS_CONCAT()只适用于oracle10.0及之前的版本。不然会报错:  ora-00904: WM_CONCAT:invalid identifier

可以改成:

select  
    listagg(t.name,',')  within  group(order by t.name)   name,
t.id id
from t group by t.id

获取特定字符串在字符串中出现的次数
语法: regexp_count(source_str, target_char [, position [, match_param]])
source_str:包含特定字符的字符串
target_char:特定字符
position: 从哪个下标开始搜索,可省略,但需>=1
match_param: 正则的匹配模式参数, 'i':忽略大小写; ‘c’或不配置该参数:不忽略大小写;此外还有‘n’、‘m’、‘x’等参数

select regexp_count(',abc,,,Ad,,ef,', ',') from dual;

行转列(oracle  11g) :

pivot(聚合函数 for 列名 in(类型))

列转行:

unpivot

在order by后面使用NLSSORT函数转化汉字列,如下
select * from student order by NLSSORT(name,'NLS_SORT=SCHINESE_PINYIN_M');
参数说明:
SCHINESE_RADICAL_M  按照部首(第一顺序)、笔划(第二顺序)排序  
SCHINESE_STROKE_M  按照笔划(第一顺序)、部首(第二顺序)排序  
SCHINESE_PINYIN_M     按照拼音排序

function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier)
__srcstr :需要进行正则处理的字符串
__pattern :进行匹配的正则表达式
__position :起始位置,从第几个字符开始正则表达式匹配(默认为1)
__occurrence :标识第几个匹配组,默认为1
__modifier :模式('i'不区分大小写进行检索;'c'区分大小写进行检索。默认为'c'。)

select regexp_substr('aaa/bbbb/ccccc','[^/]+',1,2) from dual; -- bbbb

原文地址:https://www.cnblogs.com/yrjns/p/10864087.html