Oracle04基本查询+条件查询+排序+单行函数+通用函数介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle04基本查询+条件查询+排序+单行函数+通用函数介绍相关的知识,希望对你有一定的参考价值。

一、基本查询

对于ORACLE,最常关注的无非就是关于ORACLE的查询之类的语句了,而在PL/SQL上面,笔者使用的一般有两种不同的查询窗口:CommandWindow和SQLWindow两种不同的窗口。

1.1现在将一些需要在CommandWindow使用的命令罗列如下:

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 
Connected as scott@ORCL

SQL> show user;
User is "scott"

SQL> desc emp;
Name     Type         Nullable Default Comments 
-------- ------------ -------- ------- -------- 
EMPNO    NUMBER(4)                              
ENAME    VARCHAR2(10) Y                         
JOB      VARCHAR2(9)  Y                         
MGR      NUMBER(4)    Y                         
HIREDATE DATE         Y                         
SAL      NUMBER(7,2)  Y                         
COMM     NUMBER(7,2)  Y                         
DEPTNO   NUMBER(2)    Y    

上述分别是查询当前用户的命令,以及查询表结构的命令;

 1.2基本查询

下面介绍的是一些简单的查询:

/*查询该用户下面的所有的表*/
select * from tab;
/*查询所有数据*/
select * from emp;
/*通过特点的列名查询数据*/
select empno,ename,job from emp;
/*给列名命名别名来查询数据*/
select empno    员工号,
       ename    员工名,
       job      职位,
       MGR      上司,
       hiredate 入职时间,
       sal      工资,
       comm     奖金,
       deptno   部门号
  from emp;
/*查询员工信息:员工号 姓名 月薪 年薪 奖金 年收入*/
select empno,ename,sal,sal*12,comm from emp;
/*如果不知道某一个表的列有哪些,可以给表一个简单别名,进行查询*/
select a.empno,a.ename,a.sal,a.sal*12,a.comm from emp a;

1.3NVL函数

如果,我们要查询的是某一个员工的年薪的话,那么年薪=月薪*12+奖金,虽然ORACLE进行的查询语句可以进行简单加减,但是会出现不符合我们要求的结果:

/*不使用NVL函数*/
select empno 员工号,
       ename 姓名,
       sal 薪水,
       sal * 12 年薪,
       comm 奖金,
       sal * 12 + comm 总年薪
  from emp;

结果:

技术分享

我们会发现,当没有奖金的时候,查询出来的总年薪为空,这说明了SQL语句中如果有表达式为null,那么结果为空。所以我们就会使用NVL()函数来改善结果。如下所示:

/*使用NVL函数*/
select empno 员工号,
       ename 姓名,
       sal 薪水,
       sal * 12 年薪,
       comm 奖金,
       sal * 12 + NVL(comm, 0) 总年薪
  from emp;

这时候结果为:

技术分享

解释一下NVL()函数:

  1.NVL(a,b)如果a是NULL,用b替代,如果a是非NULL,就不用b替代,直接返回a的值,NVL()作用于任何类型,即(number/varchar2/date)

  2.使用NVL2(a,b,c)通用函数,如果a不为NULL,取b值,否则取c值

1.4使用别名进行查询注意点

使用列别名,查询员工的编号,姓名,月薪,年薪,年收入(年薪+奖金),AS大小写都可且可以省略AS,别名用双引号:

select empno AS "编号",ename as "姓名",sal "月薪" 
from emp;
或者
select empno AS 编号,ename as 姓名,sal 月薪 
from emp;
或者
select empno AS "编号",ename as 姓名,sal "月    薪" 
from emp;

不加双引号的别名不能有空格;加了双引号的别名可以有空格
要加只能加双引号,不能加单引号,因为在oracle中单引号表示字符串类型或者是日期类型

1.5Oracle中哑表(伪表)的使用

/*使用dual哑表或者伪表,使用字符串连接符号||,输出"hello world",在oracle中from是必须写的*/
select ‘hello‘||‘world‘ 结果 from dual;
/*使用哑表查询当前系统时间*/
select sysdate from dual;

1.6字符连接符号的使用

/*使用字符串连接符号||,显示如下格式信息:****的薪水是****美元*/
select ename || ‘的薪水是‘ || sal || ‘美元‘ from emp;

1.7带where条件和between...and...过滤的查询

/*查询emp表中20号部门的员工信息*/
select * from emp where deptno = 20;

/*查询姓名是SMITH的员工,字符串使用‘‘,内容大小写敏感*/
select * from emp where ename = SMITH;

/*查询1980年12月17日入职的员工,注意oracle默认日期格式(DD-MON-RR表示2位的年份)*/
select * from emp where hiredate = 17-12月-80;

/*查询工资大于1500的员工*/
select * from emp where sal > 1500;

/*查询工资不等于1500的员工【!=或<>】*/
select * from emp where sal <> 1500;

/*查询薪水在1300到1600之间的员工,包括1300和1600*/
select * from emp where (sal>=1300) and (sal<=1600);
或
select * from emp where sal between 1300 and 1600;

/*查询薪水不在1300到1600之间的员工,不包括1300和1600*/
select * from emp where sal NOT between 1300 and 1600;

/*查询入职时间在"1981-2月-20"到"1982-1月-23"之间的员工*/
select * from emp where hiredate between 20-2月-81 and 23-1月-82;
注意:
1)对于数值型,小数值在前,大数值在后
2)对于日期型,年长值在前,年小值在后

/*查询20号或30号部门的员工,例如:根据ID号,选中的员工,批量删除*/
select * from emp where (deptno=20) or (deptno=30);
或
select * from emp where deptno in (30,20);

/*查询不是20号或30号部门的员工*/
select * from emp where deptno NOT in (30,20);

/*查询姓名以大写字母S开头的员工,使用%表示0个,1个或多个字符*/
select * from emp where ename like S;
等价于
select * from emp where ename = S;
select * from emp where ename like S%;
注意:
凡是精确查询用=符号
凡是不精确查询用like符号,我们通常叫模糊查询
 
/*查询姓名以大写字母N结束的员工*/
select * from emp where ename like %N;

/*查询姓名第一个字母是T,最后一个字母是R的员工*/
select * from emp where ename like T%R;

/*查询姓名是4个字符的员工,且第二个字符是I,使用_只能表示1个字符,不能表示0个或多个字符*/
select * from emp where ename like _I__;

/*插入一条姓名为‘T_IM‘的员工,薪水1200*/
insert into emp(empno,ename) values(1111,T_IM);

/*查询员工姓名中含有‘_‘的员工,使用\\转义符,让其后的字符回归本来意思【like ‘%\\_%‘ escape ‘\\‘】*/
select * from emp where ename like %\\_% escape \\;

/*插入一个姓名叫‘的员工*/
insert into emp(empno,ename) values(2222,‘‘‘‘);

/*插入一个姓名叫‘‘的员工*/
insert into emp(empno,ename) values(2722,‘‘‘‘‘‘);

/*查询所有员工信息,使用%或%%*/
select * from emp;
select * from emp where ename like %;
select * from emp where ename like %_%;

/*查询奖金为null的员工*/
select * from emp where comm is null;
注意:null不能参数=运算
      null能参数number/date/varchar2类型运算

/*查询奖金为非null的员工*/
select * from emp where comm is not null;

/*查询无佣金且工资大于1500的员工*/
select *
  from emp
 where (comm is null)
   and (sal > 1500);

/*查询工资是1500或3000或5000的员工*/ 
select * from emp where sal in (4000, 10000, 1500, 3, 300, 3000, 5000);

/*查询职位是"MANAGER"或职位不是"ANALYST"的员工(方式一,使用!=或<>)*/
select *
  from emp
 where (job = MANAGER)
    or (job <> ANALYST);

/*查询职位是"MANAGER"或职位不是"ANALYST"的员工(方式二,使用not)*/
select *
from emp
where (job=MANAGER) or (not(job=ANALYST));

1.8使用order by进行排序

/*查询员工信息(编号,姓名,月薪,年薪),按月薪升序排序,默认升序,如果月薪相同,按oracle内置的校验规则排序*/
select empno, ename, sal, sal * 12 from emp order by sal asc;

/*查询员工信息(编号,姓名,月薪,年薪),按月薪降序排序*/
select empno, ename, sal, sal * 12 from emp order by sal desc;

/*查询员工信息,按入职日期降序排序,使用列名*/
select empno, ename, sal, hiredate, sal * 12 "年薪"
  from emp
 order by hiredate desc;

/*order by后面可以跟列名、别名、表达式、列号(从1开始,在select子句中的列号)*/
列名:
select empno, ename, sal, hiredate, sal * 12 "年薪"
  from emp
 order by hiredate desc;

别名: 
select empno, ename, sal, hiredate, sal * 12 "年薪"
  from emp
 order by "年薪" desc;

表达式:
select empno, ename, sal, hiredate, sal * 12 "年薪"
  from emp
 order by sal * 12 desc;

列号,从1开始:
select empno, ename, sal, hiredate, sal * 12 "年薪"
  from emp
 order by 5 desc;

/*查询员工信息,按佣金升序或降序排列,null值看成最大值*/
select * from emp order by comm desc;

/*查询员工信息,对有佣金的员工,按佣金降序排列,当order by 和 where 同时出现时,order by 在最后*/
select * from emp where comm is not null order by comm desc;

/*查询员工信息,按工资降序排列,相同工资的员工再按入职时间降序排列*/
select * from emp order by sal desc, hiredate desc;
select * from emp order by sal desc, hiredate asc;
注意:只有当sal相同的情况下,hiredate排序才有作用

/*查询20号部门,且工资大于1500,按入职时间降序排列*/
select *
  from emp
 where (deptno = 20)
   and (sal > 1500)
 order by hiredate desc;

select * from emp where deptno in (10, 20, 30, 50, a);

1.9单行函数

单行函数:只有一个参数输入,只有一个结果输出
多行函数或分组函数:可有多个参数输入,只有一个结果输出  

/*测试lower/upper/initcap函数,使用dual哑表*/
select lower(www.BAIdu.COM) from dual;//全部小写
select upper(www.BAIdu.COM) from dual;//全部大写
select initcap(www.BAIdu.COM) from dual;//首字母大写,其余小写

/*测试concat/substr函数,从1开始,表示字符,不论中英文*/
select concat(hello,你好) from dual;//正确
select concat(hello,你好,世界) from dual;//错误,说明了参数只能有两个
select hello || 你好 || 世界 from dual;//正确
select concat(hello,concat(你好,世界)) from dual;//正确
注意:concat表示将字符连接起来
select substr(hello你好,5,3) from dual;
5表示从第几个字符开始算,第一个字符为1,中英文统一处理
3表示连续取几个字符

/*测试length/lengthb函数,编码方式为UTF8/GBK,一个中文占3/2个字节长度,一个英文一个字节*/
select length(hello你好) from dual; 
select lengthb(hello你好) from dual; 

/*测试instr/lpad/rpad函数,从左向右找第一次出现的位置,从1开始*/
select instr(helloworld,o) from dual;
注意:找不到返回0
      大小写敏感 
select LPAD(hello,10,#) from dual;//结果:#####hello
select RPAD(hello,10,#) from dual;//结果:hello#####

/*测试trim/replace函数*/
select trim(  from   he  ll                ) from dual;
select replace(hello,l,L) from dual;

/*测试round/trunc/mod函数作用于数值型*/
select round(3.1415,3) from dual;//3.142
select trunc(3.1415,3) from dual;//3.141
select mod(10,3) from dual;//1

当前日期:sysdate = 01-10月-17
/*测试round作用于日期型(month)*/
select round(sysdate,month) from dual;//2017-10-01

/*测试round作用于日期型(year)*/
select round(sysdate,year) from dual;//2018-01-01

/*测试trunc作用于日期型(month)*/
select trunc(sysdate,month) from dual;//2017-10-01

/*测试trunc作用于日期型(year)*/
select trunc(sysdate,year) from dual;//2017-01-01

/*显示昨天,今天,明天的日期,日期类型 +- 数值 = 日期类型*/
select sysdate-1 "昨天",sysdate "今天",sysdate+1 "明天" from dual;

/*以年和月形式显示员工近似工龄,日期-日期=数值,假设:一年以365天计算,一月以30天计算*/
select ename "姓名",round(sysdate-hiredate,0)/365 "天数" from emp;

/*使用months_between函数,精确计算到年底还有多少个月*/
select months_between(31-12月-15,sysdate) from dual;

/*使用months_between函数,以精确月形式显示员工工龄*/
select ename "姓名",months_between(sysdate,hiredate) "精确月工龄" from emp;

/*测试add_months函数,下个月今天是多少号*/
select add_months(sysdate,1) from dual;

/*测试add_months函数,上个月今天是多少号*/
select add_months(sysdate,-1) from dual;

/*测试next_day函数,从今天开始算,下一个星期三是多少号【中文平台】*/
select next_day(sysdate,星期三) from dual;

/*测试next_day函数,从今天开始算,下下一个星期三是多少号【中文平台】*/
select next_day(next_day(sysdate,星期三),星期三) from dual;

/*测试next_day函数,从今天开始算,下一个星期三的下一个星期日是多少号【中文平台】*/
select next_day(next_day(sysdate,星期三),星期日) from dual;

/*测试last_day函数,本月最后一天是多少号*/
select last_day(sysdate) from dual;

/*测试last_day函数,本月倒数第二天是多少号*/
select last_day(sysdate)-1 from dual;

/*测试last_day函数,下一个月最后一天是多少号*/
select last_day(add_months(sysdate,1)) from dual;

/*测试last_day函数,上一个月最后一天是多少号*/
select last_day(add_months(sysdate,-1)) from dual;

注意:
1)日期-日期=天数
2)日期+-天数=日期

1.10oracle中的三大类型的转换

oracle中三大类型与隐式数据类型转换
(1)varchar2变长/char定长-->number,例如:‘123‘->123
(2)varchar2/char-->date,例如:‘25-4月-15‘->‘25-4月-15‘
(3)number---->varchar2/char,例如:123->‘123‘
(4)date------>varchar2/char,例如:‘25-4月-15‘->‘25-4月-15‘
oracle如何隐式转换:
1)等号两边的类型是否相同
2)如果等号两边的类型不同,尝试的去做转换
3)在转换时,要确保合法合理,否则转换会失败,例如:12月不会有32天,一年中不会有13月

/*查询1980年12月17日入职的员工(方式一:日期隐示式转换)*/
select * from emp where hiredate = 17-12月-80;

/*使用to_char(日期,‘格"常量"式‘)函数将日期转成字符串,显示如下格式:2015 年 04 月 25 日 星期六*/
select to_char(sysdate,yyyy" 年 "mm" 月 "dd" 日 "day) from dual;

/*使用to_char(日期,‘格式‘)函数将日期转成字符串,显示如格式:2015-04-25今天是星期六 15:15:15*/
select to_char(sysdate,yyyy-mm-dd"今天是"day hh24:mi:ss) from dual;
或
select to_char(sysdate,yyyy-mm-dd"今天是"day HH12:MI:SS AM) from dual;

/*使用to_char(数值,‘格式‘)函数将数值转成字符串,显示如下格式:$1,234*/
select to_char(1234,$9,999) from dual;

/*使用to_char(数值,‘格式‘)函数将数值转成字符串,显示如下格式:¥1,234select to_char(1234,‘$9,999‘) from dual;*/
select to_char(1234,L9,999) from dual;

/*使用to_date(‘字符串‘,‘格式‘)函数,查询1980年12月17日入职的员工(方式二:日期显式转换)*/
select * from emp where hiredate = to_date(1980年12月17日,yyyy"年"mm"月"dd"日");
或
select * from emp where hiredate = to_date(1980#12#17,yyyy"#"mm"#"dd);
或
select * from emp where hiredate = to_date(1980-12-17,yyyy-mm-dd);

/*使用to_number(‘字符串‘)函数将字符串‘123’转成数字123*/
select to_number(123) from dual;


注意:
select 123 + 123 from dual;//246
select 123 || 123 from dual;//123123

1.11通用函数

使用NVL(a,b)通用函数,统计员工年收入,NVL()作用于任何类型,即(number/varchar2/date)
通用函数:参数类型可以是number或varchar2或date类型

使用NVL2(a,b,c)通用函数,如果a不为NULL,取b值,否则取c值,统计员工年收入

使用NULLIF(a,b)通用函数,在类型一致的情况下,如果a与b相同,返回NULL,否则返回a,比较10和10.0是否相同

使用SQL99标准通用语法中的case表达式,将职位是分析员的,工资+1000;职位是经理的,工资+800;职位是其它的,工资+400
case 字段
     when 条件 then 表达式1
     when 条件 then 表达式2
     else 表达式n
end

使用oracle专用语法中的decode()函数,职位是分析员的,工资+1000;职位是经理的,工资+800;职位是其它的,工资+400
decode(字段,条件1,表达式1,条件2,表达式2,...表达式n)

单引号出现的地方如下:
1)字符串,例如:‘hello‘
2)日期型,例如:‘17-12月-80‘
3)to_char/to_date(日期,‘YYYY-MM-DD HH24:MI:SS‘)

双引号出现的地方如下:
1)列别名,例如:select ename "姓 名" from emp
2)to_char/to_date(日期,‘YYYY"年"MM"月"DD"日" HH24:MI:SS‘)

    

以上是关于Oracle04基本查询+条件查询+排序+单行函数+通用函数介绍的主要内容,如果未能解决你的问题,请参考以下文章

MySql 01(安装,删除,简介,常用命令,简单查询,条件查询,排序,单行处理函数多行处理函数分组查询)

MySQL的排序查询和单行函数

MySQL的排序查询和单行函数

Oracle单行查询

SQL语句基本语法

Oracle!你必须要知道的Knowledge points(下)