Oracle_day01

Oracle_day01

1. Oracle简介

Oracle公司的一款关系型数据库管理系统,分布式数据库,实现了分布式处理功能。

2. Oracle数据库的体系结构

  • 数据库

    Oracle数据库是数据的物理存储,与其它数据库不同,一个操作系统只有一个Oracle数据库,可以看做Oracle就只有一个大数据库。

  • 实例

    一个Oracle实例(Oracle instance)有一系列的后台进程(background processes)和内存结构(memory structures)组成。一个数据库可以有n个实例。

  • 数据文件(dbf)

    数据文件是数据库的物理存储单位。数据库的数据是存储在表空间中的 ,真正是在某一个或多个数据库文件中。一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间。一旦数据文件被加入到某个表空间后,就不能删除这个文件,如果要删除某个数据文件,只能删除其所属的表空间才行。

  • 表空间

    表空间是Oracle对物理数据库上相关数据文件的逻辑映射。表空间由多个数据文件组成,数据文件只能属于一个表空间。表空间为逻辑单位,数据文件为物理单位。每个数据库至少有一个表空间(称为system表空间)。

  • 用户

    用户是在实例下建立的,不同实例中可以建相同名字的用户。表不是由表空间去查的,而是由用户去查的,因为不同用户可以在同一个表空间建同一个名字的表。Oracle是由用户和表空间对数据进行管理和存放的。

数据库  ---> 数据库实例  --->  表空间(逻辑单位)(用户)  ---> 数据文件(物理单位)
地球    ---> 一个国家    --->  省份(逻辑单位)(公民)    ---> 山川河流(物理单位)

3. sql简介

sql: structured query language,简称sql,结构化查询语言。用于存取数据以及查询,更新和管理数据库系统,也是数据库脚本文件的扩展名。

sql分类:

  • DDL

    数据库定义语言。create, alter, drop, truncate。

  • DML

    数据库操作语言。insert, update, delete。

  • DCL

    数据库控制语言。通过grant, revoke获取许可,确定单个用户和用户组对数据库对象的访问。

  • DQL

    数据查询语言。select...from...where。

4. sql语法

4.1 基本查询

--基本查询
select * from tab;--查询所有表
select * from emp;--查询emp表
select 1 from emp;--14*1个1
select empno,ename,job from emp;--查询表中的某些列

--别名查询,as关键字可省略
--别名中不萌有特殊字符或关键字,如果有就加双引号。
select empno as 部门编号,ename as 部门名称,job as 工作 from emp; 
select empno 部门编号,ename 部门名称,job 工作 from emp;
select empno "部门  编号",ename 部门名称,job 工作 from emp;

4.2 distinct去重

/*
   distinct去重
       单列去重:只显示非重复数据
       多列去重:整行数据完全相同时才去重
*/
select distinct job from emp;--单列去重
select distinct job,deptno from emp;--多列去重

4.3 四则运算

select 1+1;
/*
在mysql中结果为2;
在oracle中报错:from keyword not found where expected,
需要补上dual表,oracle中的虚表,伪表,主要是用来补齐语法结构
*/
select 1+1 from dual;--在oracle和mysql中都为2

4.3 nvl函数

--查询员工年薪
select sal*12 from emp;
--查询员工年薪+奖金(comm中存在null值)
select sal*12+comm from emp;--错误
/*
comm为空(null)的行查询结果显示该行也为空,因为null值表示不确定,不可预知的内容,
不能做四则运算;需要使用nvl函数,将comm为null值的在进行运算时设置为0
*/
select sal*12+nvl(comm,0) from emp;--正确

4.4 字符串拼接

/*
拼接符拼接:oracle特有字符串拼接符:||
函数拼接:concat(str1,str2),mysql和oracle中都有
*/
--查询员工姓名
--拼接符拼接
select '姓名:'||ename from emp;
--函数拼接
select concat('姓名:',ename) from emp; 
/*
oracle中单引号和双引号区别:
   双引号:关键字,对象名,字段名,别名
   单引号:指定字符串文本时,转义符
*/

4.5 条件查询

/*
   关系运算符:>  >=  =  <  <=  !=  <>(不等号)
   逻辑运算符:and or not
   其它运算符:
             like 模糊查询
             in(set) 在某个集合中
             between..and..在某个区间内
             is null 判断为空
             is not null 判断不为空
 */
 --模糊查询
 --查询员工姓名第三个字符是O的员工信息
 select * from emp where ename like '__O%';--前两位用_表示
 --查询员工姓名中包含%的员工信息
 select * from emp where ename like '%%%'; --错误,查询的是所有
 select * from emp where ename like '%\%%' escape '\'; 
select * from emp where ename like '%&%%' escape '&'; 
 --escape '\'即声明\为转义符,也可使用&等其它字符

 --查询员工工资在1500和3000之间的员工名称
 select ename from emp where sal>=1500 and sal<=3000;
 select ename from emp where sal between 1500 and 3000;
 --查询名字在某个范围的员工信息 ('JONES','SCOTT','FORD') 
 select * from emp where ename in ('JONES','SCOTT','FORD');

4.6 排序

 /*
 order by
       升序:asc  ascend(默认)
       降序:desc descend
 如果某列有null值,可指定null值排在前面和后面:nulls first,nulls last,
 默认null值在前
 同时排列多列,用逗号隔开
 */
 --查询员工信息,按奖金降序
 select * from emp order by comm desc nulls last;
 --查询部门编号和工资,按部门升序,工资降序
 select empno,sal from emp order by empno asc,sal desc;--结果还是按empno升序排列,这就导致sal近乎无序

4.7 函数

 /*
 函数必须要有返回值
 单行函数:对某一行中的某个值进行处理
        数值函数    字符函数    日期函数    转换函数    通用函数
 多行函数:对某一列的所有行进行处理
        max,min,count,sum,avg
 */
--多行函数
--统计工资总和
select sum(sal) from emp;
--查询最低工资
select min(sal) from emp;
--统计数据条数,直接写一个常量比写*更高效,也可写一个具体的列
select count(*) from emp;
select count(1) from emp;
select count(ename) from emp;

--统计平均奖金
select avg(comm) from emp;--550,显然是错误的,因为有null值
select sum(comm)/count(1) from emp;--2200/14=157.142857142857
select avg(nvl(comm,0)) from emp;--157.142857142857
--几种取整方式
--ceil(n)取大于等于n的最小整数
select ceil(sum(comm)/count(1)) from emp;--158
select ceil(-12.5) from dual;--(-12)
--floor(n)取小于等于n的最大整数
select floor(sum(comm)/count(1)) from emp;--157
select floor(-12.5) from dual;--(-13)


--round(n,t)四舍五入,t表示保留小数点后几位有效数字
--如果t为负数即处理整数部分
select round(147.128,2) from dual;--147.15
select round(147.128,0) from dual;--147
select round(147.128,-1) from dual;--150
select round(147.128,-2) from dual;--100
select round(147.128,-3) from dual;--0

--trunc(n,t)截断,t表示保留小数点后几位数字,
--如果t为负数即处理整数部分,处理完设为0
select trunc(147.128,2) from dual;--147.12
select trunc(147.128,0) from dual;--147
select trunc(147.128,-1) from dual;--140
select trunc(147.128,-2) from dual;--100
select trunc(147.128,-3) from dual;--0

--mod(n,t)求余,n/t后取余数
select mod(9,3) from dual;--0
select mod(9,2) from dual;--1

--substr(str,起始索引,长度)截取字符
--不论起始索引为0还是1,都是从第一个字符截取
select substr('abcdef',0,3) from dual;--abc
select substr('abcdef',1,3) from dual;--abc
select substr('abcdef',2,3) from dual;--bcd

--length(str)获取字符串长度
select length('abcdef') from dual;--6

--trim(str)去掉字符串左右两边空格
select trim(' abc  def ') from dual;--abc  def

--replace(str,s1,s2)替换字符,将str中的s1替换为s2
select replace('hello','l','o') from dual;--heooo


--日期函数
--sysdate查询今天日期
--查询的是oracle所在机器日期,我的oracle安装在虚拟机上,所以这是虚拟机上的日期
select sysdate from dual;

--add_months查询三个月后的今天的日期
select add_months(sysdate,3) from dual;
--查询三天后的日期
select sysdate+3 from dual;

--查询员工入职天数
select sysdate-hiredate from emp;
--查询员工入职周数
select (sysdate-hiredate)/7 from emp;
--查询员工入职月数,由于每月天数不同,所以使用months_between(date1,date2)
select months_between(sysdate,hiredate) from emp;
--查询员工入职年数
select months_between(sysdate,hiredate)/12 from emp;


--转换函数
--to_number(str)字符转数值,鸡肋,默认已经转换
select 100+'10' from dual;--110
select 100+to_number('10') from dual;--110
--to_char(n)数值转字符
select to_char(800.11) from dual;--800.11
select to_char(800.00) from dual;--800

--CL格式
--'9,999.99'用于指定格式
select to_char(1298.219,'9,999.99') from dual;--1,298.21
select to_char(1298.219, '9,999.9') from dual;--1298.2

--'0'表示在对应位置返回对应的字符,如果没有则以'0'填充
select to_char(1298.219, '9999.900') from dual;--1298.219
select to_char(1298.219, '00999.9') from dual;--01298.2
--'X'表示转换为16进制
select to_char(852,'xxxx') from dual;--354
--852/16=53余4,即个位为4;53/16=3余下5,即十位为5;3/16=0余3,即百位为3

select to_char(1298.219,'$9,999.99') from dual;--$1,298.21
select to_char(1298.219,'L9,999.99') from dual;--$1,298.21,L代表本地货币符号

--to_char()日期转字符
select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;--2020-03-15 09:07:51
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;--24小时制,2020-03-15 09:07:51
--只要年份
select to_char(sysdate,'yyyy') from dual;--2020
--只要天份
select to_char(sysdate,'d') from dual;--1  代表一周中的第几天
--今天为周日,结果为1,因为在美国周日为一周第一天
select to_char(sysdate,'dd') from dual;--15  代表一月中的第几天
select to_char(sysdate,'ddd') from dual;--75  代表一年中的第几天

select to_char(sysdate,'day') from dual;--sunday
select to_char(sysdate,'dy') from dual;--sun  sunday的简写


--字符转日期
select to_date('2020-03-15','yyyy-mm-dd') from dual;--2020/03/15转为本地日期格式
--查询1981年到1985年入职的员工信息
select * from emp where hiredate between to_date('1981','yyyy') and to_date('1985','yyyy');


--通用函数
/*
nvl(param1,param2) 如果param1=null,就返回param2
                   如果param!=null,就返回param1
nvl2(param1,param2,param3) 如果param1=null,就返回param3;
                          如果param!=null,就返回param2
nullif(param1,param2) 如果param1=param2,就返回null,否则返回param1
*/
select nvl(1,2) from dual;--1
select nvl(null,2) from dual;--2

select nvl2(1,2,3) from dual;--2
select nvl2(null,2,3) from dual;--3

--coalesce(...)返回第一个不为null的值
select coalesce(null,null,2,3) from dual;--2

4.8 条件表达式

--case...when表达式(oracle和mysql都可使用)
--给表中姓名按条件取中文名
select case ename
            when 'SMITH' then '啦啦啦'
            when 'ALLEN' then '哈哈哈'
              else '不知道'
            end "中文名"
from emp;--end指给ename这列取一个别名"中文名"
--decode(oracle特有写法)
select decode(ename,'SMITH','啦啦啦','ALLEN','哈哈哈','不知道') "中文名" from emp;

4.9 分组 group by

--查询各部门人数,按部门编号排序
select deptno,count(1) from emp group by deptno;
select deptno,count(1) from emp;--错误,不是单组分组函数
select ename,count(1) from emp group by deptno;--错误,不是分组表达式
--前面不能写后面没有的数据,除了计数

--having过滤分组数据
--查询部门平均工资大于2000的部门
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000

--错误的写法
select deptno,avg(sal) avgsal from emp group by deptno having avgsal>2000
/*
       sql的编写顺序
            select ..from..where..group by..having..order by
       sql的执行顺序
            from..where..group by..having..select..order by
 */           
--where和having的最大区别在于where后面不能有组函数,可以接单行函数

猜你喜欢

转载自www.cnblogs.com/ALiWang/p/12500006.html