Rumah > Artikel > pangkalan data > 【sql查询与优化】5.使用字符串
注:以下所有sql案例均取自oracle查询优化改写技巧与案例丛书。 1.遍历字符串 有时候要求把字符串拆分成单个字符,如: create or replace view v asselect 天天向上 as 汉字, TTXS as 首拼 from dual; 为了核对表中保存的“首拼”是否正确,需要把字符串拆分
注:以下所有sql案例均取自"oracle查询优化改写技巧与案例"丛书。create or replace view v as select '天天向上' as 汉字, 'TTXS' as 首拼 from dual;
select level from dual connect by level<br> level<br> --------<br> 1<br> 2<br> 3<br> 4<br> <br> 其中,connect by是树形查询中的一个子句,后面level是一个“伪列”,表示树形查询中的级别层次,通过level <br> 那么我们就可以通过connect by子句把v循环显示四行,并给出定位标识level:<br> select v.汉字,v.首拼,level from v connect by level <br> 汉字 首拼 LEVEL<br> ------------------------ -------- ----------<br> 天天向上 TTXS 1<br> 天天向上 TTXS 2<br> 天天向上 TTXS 3<br> 天天向上 TTXS 4<br> <br> 根据上面的数据,就可以通过函数substr(v.汉字,level,?)得到需要的结果:<br> <pre code_snippet_id="1692086" snippet_file_name="blog_20160522_3_8881054" name="code" class="sql">select v.汉字, v.首拼, level, substr(v.汉字,level,1) as 汉字拆分, substr(v.首拼,level,1) as 首拼拆分, 'substr(''' || v.汉字 || ''',' || level || ',1)' as fun from v connect by level<br> 汉字 首拼 LEVEL 汉字拆分 首拼拆分 FUN<br> ------------------------ -------- ---------- -------- -------- ----------<br> 天天向上 TTXS 1 天 T substr('天天向上',1,1)<br> <br> 天天向上 TTXS 2 天 T substr('天天向上',2,1)<br> <br> 天天向上 TTXS 3 向 X substr('天天向上',3,1)<br> <br> 天天向上 TTXS 4 上 S substr('天天向上',4,1)<br> <br> 可以看到我们是利用level的值将字符串进行拆分的,最后的fun可以看出来。<br> <br> 注:<br> substr(string,start,length)<br> string - 指定的要截取的字符串。<br> start - 必需,规定在字符串的何处开始。正数 - 在字符串的指定位置开始,负数 - 在从字符串结尾的指定位置开始,0 - 在字符串中的第一个字符处开始。<br> length - 可选,指定要截取的字符串长度,缺省时返回字符表达式的值结束前的全部字符。<br> <br> <br> 2.字符串文字包含引号<br> 常常有人写SQL时不知道在字符串内的单引号怎么写,其实只要把一个单引号换成两个单引号表示就可以。<br> <pre code_snippet_id="1692086" snippet_file_name="blog_20160522_4_8182942" name="code" class="sql">select 'g''day mate' qmarks from dual union all select 'beavers''teeth' from dual union all select '''' from dual;
select q'[g'day mate]' qmarks from dual union all select q'[beavers' teeth]' from dual union all select q'[']' from dual;
create or replace view v as select 'CLARK,KING,MILLER' as str from dual;
select length(translate(str,',' || str,','))+1 as cnt from v;
create or replace view v as select '10$#CLARK$#MANAGER' as str from dual;
select length(translate(str,'$#' || str,'$#'))/length('$#')+1 as cnt from v;
regexp_count(str,"\$#")+1 as cnt from v;
create or replace view employes as select 'CLARK' as ename from dual union all select 'KING' as ename from dual union all select 'MILLER' as ename from dual;
select ename, replace(translate(ename,'AEIOU','aaaaa'),'a','') stripped1 from employes;
select ename,translate(ename,'1AEIOU','1') stripped1 from employes;
select ename, regexp_replace(ename,'[AEIOU]') as stripped1 from employes;
select * from dept2;DATA
select regexp_replace(data,'[0-9]','') dname, regexp_replace(data,'[^0-9]','') deptno from dept2;
select translate(data,'a0123456789','a') dname, translate(data,'0123456789' || data,'0123456789') deptno from dept2;
create or replace view v as select '123' as data from dual union all select 'abc' from dual union all select '123abc' from dual union all select 'abc123' from dual union all select 'a1b2c3' from dual union all select 'a1b2c3#' from dual union all select '3$' from dual union all select 'a 2' from dual;
SQL> select * from v;
SQL> select data from v where regexp_like(data,'^[0-9a-zA-Z]+$');
create or replace view v as select 'Micheal Hartstein' as ai from dual;
select ai,lower(ai) as a2 from v;
select translate(ai,' '||a2,'.')as a3 from (select ai,lower(ai) as a2 from v);
create or replace view v as select 'ACCOUNTING 10 NEW YORK' as data from dual union all select 'OPERTIONS 40 BOSTON' as data from dual union all select 'RESEARCH 20 DALLAS' as data from dual union all select 'SALES 30 NEW CHICAGO' as data from dual;
SQL> select * from v;
select data,to_number(regexp_replace(data,'[^0-9]','')) as deptno from v order by 2;
select data, to_number(translate(data,'0123456789'||data,'0123456789')) as deptno from v order by 2;
create or replace view v as select 'CLARK,KING,MILLER' as name from dual union all select 'ADAMS,FORD,JONES,SCOTT,SMITH' as name from dual;
SQL> select * from v;
select name, 第二个逗号后的位置, 第三个逗号的位置, 长度, substr(name,第二个逗号后的位置,长度) as 子串 from (select name, instr(src.name, ',', 1, 2) + 1 as 第二个逗号后的位置, instr(src.name, ',', 1, (2+1)) as 第三个逗号的位置, instr(src.name, ',', 1, (2+1)) - instr(src.name, ',', 1, 2) - 1 as 长度 from(select ',' || name || ',' as name from v)src )x;
select regexp_substr(v.name,'[^,]+',1,2) as 子串 from v;
select regexp_substr(v.ip, '[^.]+', 1, 1) a, regexp_substr(v.ip, '[^.]+', 1, 2) b, regexp_substr(v.ip, '[^.]+', 1, 3) c, regexp_substr(v.ip, '[^.]+', 1, 4) d from (select '192.168.1.118' as ip from dual) v;
select * from emp where ename in (...);
SQL> select * from emp where ename in ('张三,李四,李磊磊');
create or replace view v as select '张三,李四,李磊磊' as emps from dual;
select regexp_substr(v.emps,'[^,]+',1,level) as name,level from v connect by level <br> NAME LEVEL<br> --------- --------<br> 张三 1<br> <br> 李四 2<br> <br> 李磊磊 3<br> <br> <br> 那么结合本句就可以达到本例的需求。<br> <pre code_snippet_id="1692086" snippet_file_name="blog_20160522_37_6684991" name="code" class="sql">SQL> var v_emps varchar2(100); SQL> exec :v_emps := '张三,李四,李磊磊';
SQL> select * from emp where ename in ( select regexp_substr(:v_emps,'[^,]+',1,level) as ename from dual connect by level <br> EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO<br> ---------- -------------------- ------------------ ---------- -------------- ---------- ---------- ----------<br> 1110 张三 主管 3322 12-3月 -14 5200 20<br> <br> 1111 李四 销售 3321 03-11月-15 3400 500 30<br> <br> 1114 李磊磊 会计 3319 22-12月-15 2500 50<br> <br> 注:exec 是 execute 的缩写,功能是执行一个存储过程,或者是执行一个动态SQL。<br> <span style="color:#FF0000"><strong><br> 转载请注明出处:http://blog.csdn.net/acmman/article/details/51473622</strong></span><br>