zoukankan      html  css  js  c++  java
  • 常用的一些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

  • 相关阅读:
    快递标示
    git 操作命令系列
    在线js调试地址
    jQuery 的 validator 验证动态添加的信息
    mysql批量插入
    array_map 批量对数据执行某个自定义方法
    使用 header函数实现文件下载
    设置UTF-8 编码
    常用短信接口平台
    async: false 实现AJAX同步请求 ( $.ajax同步/异步(async:false/true) )
  • 原文地址:https://www.cnblogs.com/yrjns/p/10864087.html
Copyright © 2011-2022 走看看