设为首页 收藏本站
查看: 277|回复: 0

[经验分享] sql的基础语句-单行函数,dual,数字函数,日期函数,表连接,集合运算,分组报表,单行子查询,多行子查询

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-2-26 08:24:39 | 显示全部楼层 |阅读模式
3. 单行函数

3.1 转换函数

select ascii('A'),chr(65) from dual;

select to_char(1243123),1231451 from dual;
靠左边的就是字符串,靠右边的就是数字

select to_char(123512a121) from dual;   --错误的写法,没有引号表示数字,但是数字里面包含了字母,不合法的输入值

select to_number('123141211') from dual;

select to_number('12314a1211') from dual;  --不合法的输入值


select to_date('20140610121212','yyyy-mm-dd hh24:mi:ss') from dual;

不合法的输入值:
select to_date('20141310121212','yyyy-mm-dd hh24:mi:ss') from dual;


select to_date(20140610121212,'yyyy-mm-dd hh24:mi:ss') from dual;  --日期不加引号,数字类型

将日期转换为固定格式字符串
select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') from dual;

select to_char(sysdate,'yyyymmdd') from dual;

select to_number(to_char(sysdate,'yyyymmdd')) from dual;

3.2 字符串的运算

(1)字符串的连接

select concat('123124','asdfda') from dual;    --只能传两个参数,但是||可以不断拼接

select '123124'||'asdfda' from dual;


(2)求长度

select length('adsfasgsadfasdf') from dual;

(3)截取串

select substr('asdfasdfasdfasdf',5,4) from dual;
从左向右第5位开始向后截取4个字节长度

select substr('asdfasdfasdfasdf',-5,4) from dual;
从右向左第5位开始向后截取4个字节长度

select length(substr('asdfasdfasdfasdf',-5,7)) from dual;    --截取完为止

(4)求子串的位置

select instr('asdfasdfasdfasdf','asdf',3,1) from dual;
从左向右第3位开始,第1次出现‘asdf’的索引位置

select instr('asdfasdfasdfasdf','asdf',3,2) from dual;
从左向右第3位开始,第2次出现‘asdf’的索引位置

select instr('asdfasdfasdfasdf','asdf',-3,2) from dual;         --9 (红色的为第一个,***开始为第二个,也就是第五个a是第二个,然后顺序再从右边第四个开始算起为1,所以也就是第九位) ;
从右向左第3位开始,第2次出现‘asdf’的索引位置
意思是说从右边的第三位开始算起,也就是从右边的第四位开始由1开始,然后第二次出现字符创的位置仍然是从左边开始的,也就是 a s d f a  s d f a,但是数字就是从右边算起
                       9 8 7 6 5 4 3 2 1
select instr('asdfasdfasdfasdf','asdf',-3,1) from dual;         --13
从右向左第3位开始,第1次出现‘asdf’的索引位置

(5)大小写的转换

select upper('asdfasgas'),lower('GHJAJDGJ') from dual;

select lower(ename),lower(job) from emp;

(6) 替换

select replace('asdfasdfasdfasdf','asdf','H') from dual;

(7) 补足字符串

select lpad('asdf',20,'*'),rpad('asdf',20,'*') from dual;

(8)去空格

select trim('     sadf      ') as a,ltrim('      asdf       ') as b,rtrim('      asdf       ') as c from dual;

(9)去中间的空格

select replace('   asdf  sdf  dfasdf  sdf    '   ,   ' '   ,   ''    ) as a from dual;
                      ‘ 字符串  ’,分隔符   ‘ ’匹配条件 ‘’匹配结果  

asdfsdfdfasdfsdf

###########################################################################################
4.数字函数

(1) 小数点后1位四舍五入

select round(2.76,1) from dual;

(2) 对整数四舍五入

select round(2.76) from dual;

(3)向上取整,ceil表示天花板

select ceil(4.3) from dual;

(4)向下取整,floor表示地板

select floor(4.8) from dual;

(5)求余数

select mod(10,3) from dual;

(6)截断

select trunc(10.454212348211,2),trunc(21154.1454211,-2) from dual;
注意:第二个参数是正数,截断小数点后面的两位
      第二个参数是负数,截断小数点前面的两位

##########################################################################################
5.日期函数

(1)截断日期

select trunc(to_date('20140610','yyyy-mm-dd'),'dd'),trunc(to_date('20140610','yyyy-mm-dd'),'mm'),
       trunc(to_date('20140610','yyyy-mm-dd'),'yyyy') from dual;

select trunc(to_date('20140610121212','yyyy-mm-dd hh24:mi:ss'),'hh'),
       trunc(to_date('20140610121212','yyyy-mm-dd hh24:mi:ss'),'mi') from dual;

(2) 两个日期之间的天数  =  两个日期相减

select sysdate - to_date('20130610095000','yyyy-mm-dd hh24:mi:ss') from dual;

(3) 月份前后推

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

第二个参数为负数,往前推
第二个参数为正数,往后推

(4) 算两个日期间隔的月数

select months_between(sysdate,to_date('20130610100000','yyyy-mm-dd hh24:mi:ss')) from dual;

例子:

   计算入职时间年数的分布:

    A:1年以内
    B:1~3年
    C:3~5年
    D: 5年以上

   select rs1,count(*) from
     (select empno,(case when rs<=1 then 'BELOW 1'
                    when rs>1 and rs<3 then '1~3'
                    when rs>=3 and rs<5 then '3~5'
                    when rs>=5 then 'over 5' end) as rs1
       from(
        select empno,round((months_between(sysdate,hiredate)/12)) as rs
          from emp
        )
     )group by rs1;

(5) decode函数
   
    F=decode(p1,p2,p3,p4,p5...,pn)
   含义:如果p1 = p2,F=p3
     如果p1 = p4,F=p5
         .....
     如果都不满足,F=pn

  select decode(deptno,10,'dept10',20,'dept20',30,'dept30','dept40') as x  from dept;
=
  select (case when deptno=10 then 'dept10'
             when deptno=20 then 'dept20'
             when deptno=30 then 'dept30'
             else 'dept40' end
        ) as x
  from dept;

(6)nvl函数

   nvl(comm,9999) -- 如果第一个参数为null,就显示第二个参数

示例:求当第一个数为null的时候,值取9999,否则等于原值

select empno,nvl(comm,9999) as x,decode(comm,null,9999,comm) as y,(case when comm is null then 9999 else comm end) as z  from emp;

###########################################################################################
6.表的连接

6.1等值连接

select b.deptno,a.ename from dept b (inner) join emp a on(a.deptno=b.deptno)
等值连接其实就是内连接


6.2左连接

select b.deptno,a.ename from dept b left (outer) join emp a on(a.deptno=b.deptno);
dept -- 主表
emp  -- 副表
编写方式:主表 left join 副表,保证主表的数据不丢失

6.3右连接

select b.deptno,a.ename from emp a right join dept b on(a.deptno=b.deptno);
dept  -- 主表
emp   -- 副表
编写方式:副表 right join 主表,保证主表的数据不丢失

oracle语法:将左右连接统一表示
select b.deptno,a.ename from emp a, dept b where a.deptno(+)=b.deptno;
select b.deptno,a.ename from emp a, dept b where b.deptno=a.deptno(+);
(+)的对面的表就是主表
dept表是主表
emp 表是副表


注意:
  A:如果副表上有过滤条件的时候,怎样满足左右连接的效果

select b.deptno,a.ename from dept b left join emp a on(a.deptno=b.deptno) where a.sal>1000;
为了加过滤条件,把主表的数据丢了,此时失去左连接的意义

select b.deptno,a.ename from dept b left join emp a on(a.deptno=b.deptno and a.sal>1000);
=
select b.deptno,a.ename from dept b,emp a where a.deptno(+)=b.deptno and a.sal(+)>1000;

  B:主表上有过滤条件,不存在这个问题

数学原理:

左连接 :   A∪(A∩B)
等值连接:  A∩B

6.4多表关联

select * from a,b,c,d where a.x=b.x and b.y=c.y and c.z=d.z;

特殊的连接:笛卡尔积
  select * from a,b

6.5非等值连接

select e.ename,s.grade,e.sal
  from emp e,salgrade s
where e.sal between s.losal and s.hisal;

salgrade:薪资等级表

6.6自连接

查询所有员工的直接上司的对应关系,表示成“员工名称 work for 上司名称”,一般用在有层级关系的表上面
  select worker.ename ||' work for '||manager.ename
  from emp worker,emp manager
where worker.mgr=manager.empno;


##########################################################################################
7 集合运算

7.1 求差集

A. not exists操作和not in 操作

select b.deptno,b.dname,b.loc from dept b
where not exists(select a.deptno from emp a where a.deptno=b.deptno);
=
select b.deptno,b.dname,b.loc from dept b
where b.deptno not in(select a.deptno from emp a where a.deptno=b.deptno);

B. minus操作

select b.deptno from dept b
minus
select a.deptno from emp a;

7.2 求交集

A exists操作 和 in操作

select b.deptno,b.dname,b.loc from dept b
where  exists(select a.deptno from emp a where a.deptno=b.deptno);
=
select b.deptno,b.dname,b.loc from dept b
where b.deptno in(select a.deptno from emp a where a.deptno=b.deptno);

B 等值连接

select distinct b.deptno,b.dname,b.loc from emp a,dept b where a.deptno=b.deptno;

7.3 求并集

A 左右连接(其中一个集合是另外一个集合的子集)

select b.deptno,a.ename from dept b left join emp a on(a.deptno=b.deptno);

B union操作

select b.deptno from dept b    --合并后去重
union
select a.deptno from emp a;

select b.deptno from dept b     --合并之后不去重
union all
select a.deptno from emp a;

7.4 求全集

select * from emp;

7.5 求子集

select * from emp where ename like 'T%';

7.6 求补集

select * from emp where ename not like 'T%';

7.7 求映射

select ename,job from emp where ename like 'T%';
在操作ename集合的时候,同时查询job字段映射的值

###########################################################################################
8.分组报表

select b.deptno,b.dname,nvl(floor(avg(a.sal)),0) as x,nvl(sum(a.sal),0) as y,nvl(min(a.sal),0) as z,nvl(max(a.sal),0) as l
  from emp a,dept b
where a.deptno(+)=b.deptno
group by b.deptno,b.dname
order by b.deptno,b.dname;

having 字句  --  对聚合函数的结果进行过滤

select b.deptno,b.dname,nvl(floor(avg(a.sal)),0) as x,nvl(sum(a.sal),0) as y,nvl(min(a.sal),0) as z,nvl(max(a.sal),0) as l
  from emp a,dept b
where a.deptno(+)=b.deptno
group by b.deptno,b.dname
having avg(a.sal)>2000
order by b.deptno,b.dname;

注意:having字句一定要放在order by的前面,group by的后面

##########################################################################################
9.单行子查询还有多行子查询

(1) 单行子查询:返回一行的子查询

   需求:显示scott员工姓名、薪水、部门号并且与其同部门的人相同信息也显示出来

   select ename,sal,deptno from emp
    where deptno=(select deptno from emp where ename='SCOTT')
  =
   select ename,sal,deptno from emp
    where deptno in (select deptno from emp where ename='SCOTT')

(select deptno from emp where ename='SCOTT')返回单行,叫做单行子查询。 =、in 叫做单行操作符

(2) 多行子查询:返回多行的子查询

  需求:显示部门10所有岗位job在全公司对应相同岗位人的姓名、薪水、部门号
   
select ename,sal,deptno from emp
where job in (select job from emp where deptno=10)
in 在这里是作为多行操作符使用

select ename,sal,deptno from emp
where job = (select job from emp where deptno=10)  
错误的写法,=是单行操作符

  A 在多行子查询中使用any操作符
  
  需求:显示全公司工资高于部门10任一员工工资的员工的姓名、薪水、部门号

select ename,sal,deptno from emp
where sal > any(select sal from emp where deptno=10)
>是单行操作符,而子查询是多行的,用any来解决语法冲突,满足'任一'这种需求

  B 在多行子查询中使用all操作符

  需求:显示全公司工资高于部门20所有员工工资的员工的姓名,薪水,部门号
  select ename,sal,deptno from emp where sal > all(select sal from emp where deptno=20)
>是单行操作符,而子查询是多行的,用all来解决语法冲突,满足'所有'这种需求

注意:
1.子查询中不能写order by
2.多行子查询不能用单行操作符匹配
3.单行子查询可以匹配多行操作符
4.子查询必须写在括号里面
5.子查询要放在比较运算符后面

10. 嵌套子查询(多个子查询)

select ename,sal,deptno from emp
where sal > (select sal from emp where empno=7876) and job = (select job from emp where empno=7369);



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-42605-1-1.html 上篇帖子: sql的基础语句-select语句中出现的操作符号 下篇帖子: plsql的环境与介绍:环境的搭建和plsql的简单介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表