Oracle(二)

第三章 Single Row Functions(单值函数)
第四章 Displaying Data from Multiple Tables(多表查询)

第三章:单值函数

函数分为:

1.单值函数
1.字符函数
2.日期函数
3.转换函数
4.数字函数
2.分组函数(后面的章节再做学习)

哑表dual
dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。
例如:
显示1+1的结果,可以看出,dual很多时候是为了构成select的标准语法
select 1+1 from dual;

字符函数
LOWER    Converts to lowercase
UPPER    Converts to uppercase
INITCAP   Converts to initial capitalization
CONCAT   Concatenates values
SUBSTR   Returns substring
LENGTH   Returns number of characters
NVL     Converts a null value

lower 把字符转为小写
例如:把’HELLO’转换为小写
select lower(‘HELLO’)
from dual;

例如:把s_emp表中的last_name列的值转换为小写
select lower(last_name)
from s_emp;

upper 把字符转换为大写
例如:把’world’转换为大写
select upper(‘world’)
from dual;

例如:把s_emp表中的last_name列的值转换为大写
select upper(last_name)
from s_emp;

例如:查询s_emp表中名字为Ngao的人信息
这样是查不到:
select last_name,salary,dept_id
from s_emp
where last_name=‘NGAO’;
这样就可以查询到了:
select last_name,salary,dept_id
from s_emp
where upper(last_name)=‘NGAO’;

initcap 把字符串首字母大写
例如:把’hELLO’转换为首字母大写,其余字母小写
select initcap(‘hELLO’)
from dual;

concat 把俩个字符串连接在一起(类似之前的||的作用)
例如:把’hello’和’world’俩个字符串连接到一起,并且起个别名为msg
select concat(‘hello’,‘world’) msg
from dual;

例如:把first_name和last_name俩个列的值连接到一起
select concat(first_name,last_name) as name
from s_emp;

substr 截取字符串
例如:截取’hello’字符串,从第2个字符开始(包含第二个字符),截取后面连续的3个字符
select substr(‘hello’,2,3)
from dual;

length 获得字符串长度
例如:获得’world’字符串的长度
select length(‘world’)
from dual;

例如:获得s_emp表中last_name列的每个值的字符长度
select length(last_name)
from s_emp;

nvl 替换列中为null的值
在前面的章节已经使用过了

数字函数
ROUND Rounds value to specified decimal
TRUNC Truncates value to specified decimal
MOD Returns remainder of division

round 四舍五入
round(arg1,arg2)
第一个参数表示要进行四舍五入操作的数字
第二个参数表示保留到哪一位

例如:
保留到小数点后面2位
select round(45.923,2)
from dual;

保留到个位 (个十百千万…)
select round(45.923,0)
from dual;

保留到十位 (个十百千万…)
select round(45.923,-1)
from dual;

trunc 截取到某一位
trunc(arg1,arg2)
和round的用法一样,但是trunc只舍去不进位

例如:
截取到小数点后面2位
select trunc(45.929,2)
from dual;

截取到个位 (个十百千万…)
select trunc(45.923,0)
from dual;

截取到十位 (个十百千万…)
select trunc(45.923,-1)
from dual;

mod 取余
mod(arg1,arg2)
第一个参数表示要进行取余操作的数字
第二个参数表示参数1和谁取余

例如:
把10和3进行取余 (10除以3然后获取余数)
select mod(10,3)
from dual;

日期函数
MONTHS_BETWEEN Number of months between two dates
ADD_MONTHS Add calendar months to date
NEXT_DAY Next day of the date specified
LAST_DAY Last day of the month
ROUND Round to date at midnight
TRUNC Remove time portion from date

sysdate关键字
表示系统的当前时间
例如:
显示时间:当前时间
select sysdate from dual;

注意:sysdate进行加减操作的时候,单位是天
例如:
显示时间:明天的这个时候
select sysdate+1 from dual;

例如:
显示时间:昨天的这个时候
select sysdate-1 from dual;

例如:
显示时间:1小时之后的这个日期
select sysdate+1/24 from dual;

months_between 俩个日期之间相差多少个月(单位是月)
例如:
30天之后和现在相差多少个月
select months_between(sysdate+30,sysdate)
from dual;

add_months 返回一个日期数据:表示一个时间点,往后推x月的日期
例如:
'01-2月-2016’往后推2个月
select add_months(‘01-2月-2016’,2)
from dual;

例如:
当前时间往后推4个月
select add_months(sysdate,4)
from dual;

注意:这个数字也可以是负数,表示往前推x月

next_day 返回一个日期数据:表示一个时间点后的下一个星期几在哪一天
例如:
离当前时间最近的下一个星期5是哪一个天
select next_day(sysdate,‘星期五’)
from dual;
注意:
如果要使用’FRIDAY’,那么需要把当前会话的语言环境修改为英文

last_day 返回一个日期数据:表示一个日期所在月份的最后一天
例如:
当前日期所在月份的最后一天(月底)
select last_day(sysdate)
from dual;

round 对日期进四舍五入,返回操作后的日期数据
例如:
把当前日期四舍五入到月
select round(sysdate,‘MONTH’)
from dual;
测试:15号16号分别是舍弃还是进位

把当前日期四舍五入到年
select round(sysdate,‘YEAR’)
from dual;

trunc 对日期进行截取 和round类似,但是只舍弃不进位

类型转换函数
TO_CHAR converts a number or date string to a character string.
TO_NUMBER converts a character string containing digits to a number.
TO_DATE converts a character string of a date to a date value.

to_char 把日期转换为字符

例如:
把当前日期按照指定格式转换为字符串
select to_char(sysdate,‘yyyy’)
from dual;

日期格式:
yyyy:四位数的年份
rrrr:四位数的年份
yy:两位数的年份
rr:两位数的年份
mm:两位数的月份(数字)
D:一周的星期几
DD:一月的第几天
DDD :一年的第几天
YEAR:英文的年份
MONTH:英文全称的月份
mon:英文简写的月份
ddsp:英文的第几天(一个月的)
ddspth:英文序列数的第几天(一个月的)
DAY:全英文的星期
DY:简写的英文星期
hh:小时
mi:分钟
ss:秒

例如:
测试常见的一些日期数据转换为字符串的格式
select to_char(sysdate,‘yyyy MM D DD DDD YEAR MONTH ddsp ddspth DAY DY’) from dual;

select to_char(sysdate,‘dd-mm-yy’)
from dual;

select to_char(sysdate,‘dd-mm-yy HH24:MI:SS AM’)
from dual;

千年虫:
在早期的计算机的程序中规定了的年份仅用两位数来表示。也就是说,假如是1971年,在计算机里就会被表示为71,但是到了2000年的时候这个情况就出现了问题,计算机就会将其年份表示为00。这样的话计算机内部对年份的计算就会出现问题。这个事情当时被称为千年虫

数据库中表示日期中年份的有俩种: yy和rr
之前一直使用的时候yy格式,后来才有的rr格式
yy表示使用一个俩位数表示当前年份:
1990 —yy数据库格式—> 90
1968 —yy数据库格式—> 68
1979 —yy数据库格式—> 79

rr格式表示: 另外参照图片:rr日期格式规则.png
如果日期中的年份采用的格式为rr,并且只提供了最后2位年份,那么年份中的前两位数字就由两部分共同确定:提供年份的两位数字(指定年),数据库服务器上当前日期中年份的后2位数字(当年)。确定指定年所在世纪的规则如下:
规则1 如果指定年在0049之间,并且当前年份在0049之间,那么指定年的世纪就与当前年份的世纪相同。因此,指定年的前两位数字就等于当前年份的前两位数字。例如,如果指定年为15,而当前年份为2007,那么指定年就是2015。
规则2 如果指定年在5099之间,并且当前年份在0049之间,那么指定年的世纪就等于当前年份的世纪减去1。因此,指定年的前两位数字等于当前年份的前两位数字减去1。例如,如果指定年为75,而当前年份为2007,那么指定年就是1975。
规则3 如果指定年在0049之间,并且当前年份在5099之间,那么指定年的世纪就等于当前年份的世纪加上1。因此,指定年的前两位数字等于当前年份的前两位数字加上1。例如,如果指定年为15,而当前年份为2075,那么指定年就是2115。
规则4 如果指定年在5099之间,并且当前年份在5099之间,那么指定年的世纪就与当前年份的世纪相同。因此,指定年的前两位数字就等于当前年份的前两位数字。例如,如果指定年为55,而当前年份为2075,那么指定年就是2055。

注意:rr格式并没有完全的解决俩位数年份保存的问题,思考里面还有哪些问题存在。

to_char 把数字转换为字符
例如:
select to_char(salary,’$999,999.00’)
from s_emp;

fm表示去除结果显示中的开始的空格
select to_char(salary,‘fm$999,999.00’)
from s_emp;

L表示系统本地的货币符号
select to_char(salary,‘fmL999,999.00’)
from s_emp;

to_number 把字符转换为数字
例如:
select to_number(‘1000’)
from dual;

//这个写法是错的 abc不能转换为数字
select to_number(‘abc’)
from dual;

to_date 把字符转换为日期
例如:
select to_date(‘10-12-2016’,‘dd-mm-yyyy’)
from dual;

select to_date(‘25-5月-95’,‘dd-month-yy’)
from dual;

select to_date(‘95/5月/25’,‘yy/month/dd’)
from dual;

//session语言环境设置为英文下面可以运行
select to_date(‘25-MAY-95’,‘dd-MONTH-yy’)
from dual;

oracle数据库中表示一个日期数据的几种方式
1.使用sysdate
2.使用oracle默认的日期格式 例如:‘25-MAY-95’
3.使用日期函数ADD_MONTHS/NEXT_DAY/LAST_DAY/ROUND/TRUNC
4.使用转换函数to_date

函数之间的嵌套
格式:F3(F2(F1(arg0,arg1),arg2),arg3)
例如:
先把’hello’和’world’连接起来,再转换为字母大写然后再从第4个字符开始,连着截取4个字符
select substr(upper(concat(‘hello’,‘world’)),4,4)
from dual;

第四章:多表查询

多表查询,又称表联合查询,即一条语句涉及到的表有多张,数据通过特定的连接进行联合显示.

笛卡尔积

在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y.
假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
在数据库中,如果直接查询俩张表,那么其查询结果就会产生笛卡尔积
例如:
select *
from s_emp,s_dept;

连接查询

为了在多表查询中避免笛卡尔积的产生,我们可以使用连接查询来解决这个问题.
连接查询分为:
1.等值连接
2.不等值连接
3.外连接
左外连接
右外连接
全连接
4.自连接

等值连接

利用一张表中某列的值和另一张表中某列的值相等的关系,把俩张表连接起来。
例如:查询员工的名字、部门编号、部门名字
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id;

为了表述的更加清楚,可以给每张表起别名
select se.last_name,se.dept_id,sd.name
from s_emp se,s_dept sd
where se.dept_id=sd.id;

不等值连接

假设数据库中还有一张工资等级表:salgrade
工资等级表salgrade:
gradeName列表示等级名称
losal 列表示这个级别的最低工资数
hisal 列表示这个级别的最高工资数

表中的数据类似于下面内容:
id salgrade losal hisal
1 初级程序员 2000 4000
2 中级程序员 4000 6000

例如:
查询出员工的名字、职位、工资、工资等级名称
SELECT e.last_name, e.title, e.salray, s.gradeName
FROM s_emp e, salgrade s
WHERE e.salray BETWEEN s.losal AND s.hisal

外连接

外连接分为:左外连接 右外连接 全连接
先分别在俩s_emp和s_dept表中插入新的数据
特点:新员工tom不在任何部门,新增部门st下面没有任何员工
insert into s_emp(id,last_name) values(26,‘tom’);
insert into s_dept(id,name) values(60,‘st’);
commit;

下面条sql语句可以把上面插入的数据给删除掉
delete from s_emp where id=26;
delete from s_dept where id=60;
commit;

这个时候再使用等值连接的话,查询出来的数据就会少,因为新增的员工tom和部门表中的数据连接不上,当然新增的部门st也和员工表中的数据连接不上.那么这俩条数据都是在等值连接中查询不出来.

左外连接

例如:
查询所有员工 以及对应的部门的名字,没有部门的员工也要显示出来
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+);

或者 俩者是等价的

select last_name,dept_id,name
from s_emp left outer join s_dept
on s_emp.dept_id=s_dept.id;

注意:outer可以省去不写

右外连接

例如:
查询所有员工 以及对应的部门的名字,没有任何员工的部门也要显示出来
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

select last_name,dept_id,name
from s_emp right outer join s_dept
on s_emp.dept_id=s_dept.id;

注意:outer可以省去不写

全连接

例如:
查询所有员工 以及对应的部门的名字,没有任何员工的部门也要显示出来,没有部门的员工也要显示出来
select last_name,dept_id,name
from s_emp full outer join s_dept
on s_emp.dept_id=s_dept.id;

注意:outer可以省去不写

自连接

一张表,自己和自己连接
例如:
查询每个员工的名字以及员工对应的管理者的名字
select s1.last_name,s2.last_name manager_name
from s_emp s1,s_emp s2
where s1.manager_id = s2.id;

对查询结果集的操作
如果有俩条sql语句,每一条sql都可以查询出一个结果,这个被称之为结果集。那么我们可以使用下面的关键字对俩个结果集进行操作
union 取俩个结果集的并集
union all 把俩个结果集合在一起显示出来
minus 第一个结果集除去第二个结果集和它相同的部分
intersect 求俩个结果集的交集

注意:前提条件 俩个结果集中查询的列要完全一致

union 取俩个结果集的并集
例如:
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
union
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

union all 把俩个结果集合在一起显示出来
例如:
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
union all
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

minus 第一个结果集除去第二个结果集和它相同的部分
例如:
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
minus
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

对比俩种情况的结果

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id
minus
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+);

intersect 求俩个结果集的交集
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
intersect
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

oracle中的伪列 rownum
伪列rownum,就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。它会根据返回的结果为每一条数据生成一个序列化的数字.rownum是oracle才有的伪列

rownum 所能作的操作:

rownum 只能等于1 如果让其等于其他数 则查不到数据
例如:
select last_name
from s_emp
where rownum=1

rownum 大于0 如果让其大于其他数 则查不到数据
例如:
select last_name
from s_emp
where rownum>0

rownum 可以小于任何数
例如:
select last_name
from s_emp
where rownum<7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值