ORCALE数据库(二) --- 常用函数

本篇文章比较长,请耐心查看,有问题可以在下面评论交流,喜欢博主的可以点个关注和收藏。
首先解决上篇文章遗留的问题

当某一列全空,对该列使用聚合函数会出现下面的情况

可能出现空值的聚合函数:MIN() MAX() SUM() AVG() 不可能出现空值:COUNT()

文章目录

      • 一、转换函数
        • 1 转字符 TO_CHAR()
        • 1.1 数值转字符
          • 1) 指定精度(常用):
          • 2) 指定货币(不常用):
        • 1.2 日期转字符
          • 1) **年份** `常用`
          • 2) 季度 `常用`
          • 3) 月份
          • 4) 星期
          • 5) 天
          • 6) 小时
          • 7) 分钟
          • 8) 秒
          • 9) 毫秒
        • 2 转数值 TO_NUMBER()
        • 3 转日期 TO_DATE()
        • 4 补充 (日期的加减)
      • 二、字符型函数
        • 1 针对字符串,且返回值仍为字符串
          • 1.1 连接函数
          • 1.2 大小写函数
          • 1.3 替换函数
          • 1.4 去除函数
          • 1.5 截取函数
          • 1.6 填充函数
        • 2 针对字符串,且返回值是数值
          • 2.1 获取字符长度
          • 2.2 获取字符位置
      • 三、数值型函数
        • 1 取绝对值
        • 2 向上取整和向下取整
        • 3 取余
        • 4 四舍五入
        • 5 截断
      • 四、日期型函数
        • 1 日期函数的四舍五入和截断
          • 1.1 省略精度
          • 1.2 年的界限
          • 1.3 月的界限
          • 1.4 季的分界线
          • 1.5 小时的界限
          • 1.6 星期的界限
        • 2 获取月份的差值
        • 3 获取月末日期
        • 4 月份加减
        • 5 获取下个周几
      • 五、其他函数
        • 1 条件取值
        • 2 返回集合中第一个不为空的内容
        • 3 空值的赋值
        • 4 去重

一、转换函数

按转换的形式分为:

​ 显式转换:数据类型的转换是用户主动执行转换函数而实现的

​ 隐式转换:数据类型的转换是系统自动执行转换函数而实现的

SELECT * FROM EMP WHERE SAL = '3000'; -- 隐式转换
SELECT * FROM EMP WHERE SAL = TO_NUMBER('3000') -- 显式转换 后面会提到这个函数

1 转字符 TO_CHAR()

1.1 数值转字符

无指定格式:单纯的由数值转换为字符

SELECT TO_CHAR(123) FROM DUAL; -- 字符型靠右边显式 

有指定格式:将数值转换为字符的同时指定格式精度 和 货币)

1) 指定精度(常用):

数值转字符中的通配符:通常用0或9来代指该位的内容

9:指任意数字,若整数位无数字则格式不生效,小数位无数字以0补全

0:指任意数字,若整数位无数字,则强制显示位0,小数位一般不用0代替

***注意***:

转换过程中若遇小数位精度过低的情况,则会遵循四舍五入

遇整数位精度过低的情况,则会显示为#

可添加千分符

SELECT 123,TO_CHAR(123,'999.99') FROM DUAL; -- 结果123.00
SELECT 123,TO_CHAR(123,'999999.99') FROM DUAL; -- 结果123.00
SELECT 123,TO_CHAR(123,'00999.99') FROM DUAL; -- 结果00123.00
SELECT 123.456,TO_CHAR(123.456,'00999.00000') FROM DUAL; -- 结果00123.45600
SELECT 123.456,TO_CHAR(123.456,'99.9')FROM DUAL;  --- 精度不够 显示 #####
SELECT TO_CHAR(123.45,'999.9') FROM DUAL;  -- 结果 123.5
SELECT TO_CHAR(123456789.987,'99999,9999.999') FROM DUAL; -- 12345,6789.987

-- 进阶练习
SELECT TO_CHAR(999.99,'999.99') FROM DUAL; -- 999.99
SELECT TO_CHAR(999.99,'999.9') FROM DUAL; -- #### 1000.0 精度不够
SELECT TO_CHAR(999.99,'999,99') FROM DUAL; -- 10,00
SEELCT TO_CHAR(999.99,'999,9') FROM DUAL; -- 100,0
2) 指定货币(不常用):

$:美元符号

L:当地货币

SELECT TO_CHAR(123.45,'$999.99') FROM DUAL;  -- $123.45
SELECT TO_CHAR(123.45,'999.9$9') FROM DUAL;  -- ERROR
SELECT TO_CHAR(123.45,'99$9$.99') FROM DUAL; -- ERROR
SELECT TO_CHAR(123.45,'L999.99') FROM DUAL;  -- ¥123.45

1.2 日期转字符

SYSDATE:获取当前日期和时间

SYSTIMESTAMP:更详细的时间 毫秒级别

SELECT SYSDATE,SYSTIMESTAMP FROM DUAL; -- 获取当前日期
-- 2021/03/12 22:00:56   12-3月 -21 10.00.56.507000 下午 +08:00

日期格式的设置:固定字母或关键词来代指日期中的某一项内容,其中可以穿插一些分隔符号,且这些关键词可以随意搭配及更改顺序

1) 年份 常用

YYYY:四位年份
YYY:后三位年份 YY:后两位年份 Y:年份的最后一位

SELECT TO_CHAR(SYSDATE,'YYYY') FROM DUAL; -- 2021
SELECT TO_CHAR(SYSDATE,'YYYYYYY') FROM DUAL; -- 2021021 从前往后匹配四位,剩下的按照 YYY YY Y 显示
2) 季度 常用

Q:一年中的第几个季度(结果为一位)Q不区分大小写

SELECT TO_CHAR(SYSDATE,'Q') FROM DUAL; -- 返回当前月份所在的季度
3) 月份

MONTH:月份的全称(右侧空格补齐九位),针对英文来说

MON:三位字符的月份缩写,针对英文来说 [显示英文 需要加上 ‘NLS_DATE_LANGUAGE = AMERICAN’]

MM:一年中的第几个月(两位) 常用

SELECT TO_CHAR(SYSDATE,'MM') FROM DUAL;  --- 03 月
SELECT TO_CHAR(SYSDATE,'MONTH','NLS_DATE_LANGUAGE = AMERICAN') FROM DUAL; 
SELECT TO_CHAR(SYSDATE,'MON','NLS_DATE_LANGUAGE = AMERICAN') FROM DUAL; 
4) 星期
  • WW:一年中的第几个星期,从一年中的第一天开始算,一个七天作为一周,与星期几无关
  • IW:一年中的第几个星期,星期一作为本周的第一天。每年末最后一周不足四天,算到下一年的第一周足四天将下年本周的剩余时间一同算作本年最后一周
  • W:一个中的第几个星期,从第一天开始算起,一个七天作为一周,和星期几无关
  • DAY:星期几全称(右侧空格补齐九位) 显示英文 需要加上 ‘NLS_DATE_LANGUAGE = AMERICAN’
  • DY:星期几的三位缩写 也是英文
1 WW
SELECT TO_CHAR(SYSDATE,'WW') FROM DUAL;  -- 2021/03/13 一年中的第11周 
2 IW
SELECT TO_CHAR(TO_DATE('20210101','YYYYMMDD'),'IW') FROM DUAL;-- 第53周 算到上一年的最后一周了
SELECT TO_CHAR(TO_DATE('20191230','YYYYMMDD'),'IW') FROM DUAL; -- 算到2020年第一周
3 W
SELECT TO_CHAR(SYSDATE,'W') FROM DUAL; -- 3月的第二个周
4 DAY
SELECT TO_CHAR(SYSDATE,'DAY','NLS_DATE_LANGUAGE=AMERICAN') FROM DUAL;  -- SATURDAY  周六
5 DY
SELECT TO_CHAR(SYSDATE,'DY','NLS_DATE_LANGUAGE=AMERICAN') FROM DUAL; -- SAT 周六
5) 天

D:星期中的第几天 从星期日开始算第一天

DD:月份中的第几天,两位 常用

DDD:月份中的第几天,三位

SELECT TO_CHAR(SYSDATE,'D') FROM DUAL; -- 2021/03/13 第七天
SELECT TO_CHAR(SYSDATE,'DD') FROM DUAL; -- 第13天
SELECT TO_CHAR(SYSDATE,'DDD') FROM DUAL; -- 一年中的第 072 天
6) 小时

HH, HH12:一天中的第几个小时(12小时制);如果区分上午下午 可以加上AM PM,但显示以实际为准

HH24:一天中的第几个小时(24小时制) 常用

SELECT TO_CHAR(SYSDATE,'HH24') FROM DUAL; -- 07
SELECT TO_CHAR(SYSDATE,'HH') FROM DUAL;  -- 07
SELECT TO_CHAR(SYSDATE,'HH12 AM') FROM DUAL; -- 07 上午
SELECT TO_CHAR(SYSDATE,'HH12 PM') FROM DUAL; -- 07 上午
7) 分钟

MI:一小时中的第几分钟

SELECT TO_CHAR(SYSDATE,'MI') FROM DUAL; -- 07:57  57
8) 秒

SS:一分钟中的第几秒

SELECT TO_CHAR(SYSDATE,'SS') FROM DUAL; 
9) 毫秒

FF:默认六位

FF3 FF6:FF后面的数字表示毫秒显示位数

2 转数值 TO_NUMBER()

只含有数字的字符串转化为数值

去掉字符串中的特定符号(千分符和美元符)并将剩下的数字转化为数值

SELECT TO_NUMBER('12334') FROM DUAL; -- 12334 左靠齐
SELECT TO_NUMBER('SDD445SDFD') FROM DUAL; -- 出错 不是纯数字
SELECT TO_NUMBER('123,456,789','999999999.99') FROM DUAL; -- 123456789
SELECT TO_NUMBER('$123,456,789','$999999999.99') FROM DUAL; -- 123456789

3 转日期 TO_DATE()

TO_DATE(字符串表示的日期,’与前者对应的日期格式’)

一般需要和TO_CHAR() 连用

SELECT TO_DATE('20210312 09:27:30','YYYYMMDD HH24:MI:SS') FROM DUAL;

-- 字符2021/03/13 变成2021-03-13 
SELECT TO_CHAR(TO_DATE('2021-03/13','YYYY/MM/DD'),'YYYY-MM-DD') FROM DUAL;

4 补充 (日期的加减)

日期的加减:+1 表示加一天,换句话说日期的加减是按天计算的

两个日期型数据,不能做加法,只能做减法得到的是天数

SELECT SYSDATE+1 FROM DAUL; -- 2021/03/14 8:22:52  
SELECT TO_DATE('2021-12-31','YYYY-MM-DD') - TO_DATE('2021-12-30','YYYY-MM-DD') FROM DUAL;  -- 得到天数 

SELECT TO_DATE('2021-12-31','YYYY-MM-DD') + TO_DATE('2021-12-30','YYYY-MM-DD') FROM DUAL;  --不能相加 错误

二、字符型函数

1 针对字符串,且返回值仍为字符串

1.1 连接函数

CONCAT(STR1,STR2):将括号内的两个字符串合并到一起.

ORCALE中的CONCAT只能将两个字符串进行合并

1.2 大小写函数
  • UPPER(STR):转大写 所有字母都大写

  • LOWER(STR):转小写 所有字母都小写

  • INITCAP(STR):将字符串STR中的每个单词改成首字母大写其他字母手写(多个单词可以用空格及其他符号隔开 / $ ,

    SELECT 'SMITH ALLEN' ENAME,INITCAP('SMITH ALLEN') FROM DUAL; -- Smith Allen
    SELECT 'SMITH''ALLEN' ENAME,INITCAP('SMITH''ALLEN') FROM DUAL; -- 单引号成对出现
    SELECT 'SMITH2ALLEN' ENAME,INITCAP('SMITH2ALLEN') FROM DUAL;  -- Smith2allen  数字不作为分割符
    
1.3 替换函数

REPLACE(STR,S1,S2):将STR中的S1替换成S2。所有S1都要换成S2 当成整体

其中S1和S2视为一个整体,不能单独看其中的某个字符

不写S2默认为空 ‘’

SELECT REPLACE('SSDDDFFFS','S','E') FROM DUAL; -- EEDDDFFFE
SELECT REPLACE('2020-01-12','-','/') FROM DUAL;
SELECT REPLACE('ABCDEF','A%F','WWW') FROM DUAL;  -- 通配符 无效
1.4 去除函数
  • TRIM(STR):去除两侧空格 默认去除函数 ,只能去除单个字符

  • LTRIM(STR [,S]):去除左侧空格,可以去除字符串 多个字符

  • RTRIM(STR [,S]):去除右侧空格,可以去除字符串 多个字符

  • TRIM([LEADING/TRAILING/BOTH] [S FROM] STR)

    ​ LEADING:去除头部S字符

    ​ TRAILING:去除尾部S字符

    ​ BOTH : 去除两侧字符

    SELECT TRIM(LEADING 'A' FROM 'ABCDA') FROM DUAL; -- 去除左侧的A  BCDA
    SELECT TRIM(TRAILING 'A' FROM 'ABCDA') FROM DUAL; -- 去除右侧的A   ABCD
    SELECT TRIM(BOTH 'A' FROM 'ABCDA') FROM DUAL; -- 去除两侧的A  BCD
    

    注意:LTRIM() RTRIM()中的S若有多个字符,去除时挨个检索S中的每一个字符而不是视为一个整体

1.5 截取函数

SUBSTR(STR,IND [, LEN]):从字符串STR的IND位置,截取LEN长度的字符串并返回该截取内容

针对字符 一个汉字 一个字母 一个符号都是一个字符

拓展: SUBSTRB() 针对字节 这里指存储长度 一个汉字对应的字节数和字符集有关

注意

1 从0位开始截取,相当于从1位开始截取

2 如果IND参数为正,表示从左向右定位;如果IND参数为负,表示从右向左定位

3 无论IND参数是正还是负,截取都是从左向右截取

4 若LEN参数为0或者为负,截取结果返回空值

5 若LEN参数已超出STR实际长度,则截取到末尾

6 LEN参数可以省略,表示截取到末尾,而IND参数必不可少

7 无论IND 还是LEN 出现小数 都会被忽

SELECT ENAME,SUBSTR(ENAME,0,2) FROM EMP; -- 起始位置为0和起始位置为1的效果相同
SELECT ENAME,SUBSTR(ENAME,-2,2) FROM EMP;  -- 起始位置为负数,定位时从右往左,截取仍是从左往右
SELECT ENAME,SUBSTR(ENAME,-2,0) FROM EMP; -- 截取长度为0 结果为空
SELECT ENAME,SUBSTR(ENAME,-2,-2) FROM EMP; -- 截取长度为负数 截取结果也是为空
SELECT ENAME,SUBSTR(ENAME,2,100) FROM EMP; -- 截取长度超过剩余长度,则有多少截多少
SELECT ENAME,SUBSTR(ENAME,2) FROM EMP; -- 不指定截取长度,则截到末位
SELECT ENAME,SUBSTR(ENAME,-200,2) FROM EMP; -- 截取长度超长,截取结果为空  √
SELECT ENAME,SUBSTR(ENAME,200,2) FROM EMP; -- 空
SELECT ENAME,SUBSTR(ENAME,-200) FROM EMP; -- 空  
SELECT ENAME,SUBSTR(ENAME,1,1.5) FROM EMP; -- 无论起始位置 还是长度 出现小数 都会被忽略
1.6 填充函数

LPAD(STR,N,S):在字符串STR左侧,填充S字符,使长度达到N

RPAD(STR,N,S):在字符串STR右侧,填充S字符,使长度达到N

不指定S 填充空格

S可以是某一个字符,也可以是一段字符串,若S是字符串,填充时会循环使用S中的每一个字符

尽量避免填充后的长度比STR小 出现这种之后会出现从左侧截取N个长度的字符

SELECT LPAD('ABCDEF',4,'=') FROM DUAL; -- ABCD
SELECT RPAD('ABCDEF',4,'=') FROM DUAL; -- ABCD
SELECT LPAD('ABCDEF',7,'') FROM DUAL;  -- 填充物空 返回结果为空
SELECT RPAD('今天冻成',6,'狗') FROM DUAL; -- 填充长度按照字节来算

LPAD RPAD 针对字节 指的是显示长度,一个汉字对应的字节数固定为两个字节

2 针对字符串,且返回值是数值

2.1 获取字符长度

LENGTH(STR):返回字符串STR的字符长度 针对的就是字符

LENGTHB(STR):返回字符串STR的字符

SELECT LENGTH('ABCDE') FROM DUAL;
SELECT * FROM EMP WHERE LENGTH(ENAME) = 5;
SELECT LENGTH('今天冻成狗'),LENGTHB('明天冻成狗') FROM DUAL; -- 5 10
2.2 获取字符位置

INSTR(STR,S,IND,N):从第IND位开始,查找S在字符串中第N次出现的位置 针对字符

一般用法:INSTR(STR,S):查找字符串S在STR中第一次出现的位置

INSTRB() 针对字节

SELECT INSTR('ABCDEF','B') FROM DUAL ;  -- 2
SELECT INSTR('ABCDEF','CD') FROM DUAL;  -- 3  返回目标首位所在的位置
SELECT INSTR('ABCDEF','CF') FROM DUAL; --  0   视为整体
SELECT INSTR('ABCDEABCDE','B',3) FROM DUAL;  -- 7  无论起始位置从哪开始,返回所在位置都是从字符首位开始

注意

1)IND=0,返回0

SELECT INSTR('ABCDE','B',0) FROM DUAL;  -- 0

2)IND<0,代表从右侧开始数起,第N次出现S的位置,返回位置时仍从左侧开始算起。

SELECT INSTR('ABCDE','B',-2) FROM DUAL;  -- 2  定位:从右向左  查找:从右往左数 返回位置从左向右

3)IND超出字符总长时,返回0

SELECT INSTR('ABCDE','B',6) FROM DUAL;  --0

4)N<=0,会报错

SELECT INSTR('ABCDE','B',1,0) FROM DUAL; -- error
SELECT INSTR('ABCDE','B',1,-2) FROM DUAL; -- error

5)N超过S在字符串中出现的次数,返回0

SELECT INSTR('AABBCCDD','B',2,3) FROM DUAL; -- 0

6)IND和N是小数,按整数部分运行

三、数值型函数

1 取绝对值

ABS(NUM):一般对计算结果进行取绝对值

SELECT ABS(1.23),ABS(-4.56) FROM DUAL;

2 向上取整和向下取整

CELL(NUM):向上取整,得到距离NUM最近的两个整数中较大的那个数

FLOOR(NUM):向下取整,得到距离NUM最近的两个整数中较小的那个数

无论正数还是负数 上:数轴指向的方向; 下:数轴背向的方向

SELECT CEIL(1.23) FROM DUAL; -- 2
SELECT FLOOR(1.23) FROM DUAL; -- 1
SELECT CEIL(-1.23) FROM DUAL; -- -1
SELECT CEIL(123),FLOOR(123) FROM DUAL; -- 123 123  -- 整数返回本身

3 取余

MOD(X,Y):X除以Y得到的余数

分库分表方面应用取余函数

SELECT MOD(17,5) FROM DUAL;

4 四舍五入

ROUND(NUM [,P]):对数值NUM进行四舍五入,其中P表示精度

1 精度为0或者省略

SELECT ROUND(4.54321,0),ROUND(4.54321) FROM DUAL;  -- 5 5  看小数点后面第一位 进行进位

2 负数的四舍五入

SELECT ROUND(-1.4),ROUND(-1.6) FROM DUAL; -- -1 -2  去掉负号 按照正数规则左四舍五入 再加上负号

3 精度为负数 -1 保留到十位 -2 保留到百位后面全部清0

SELECT SELECT ROUND(45.321,-1),ROUND(45.321,-2),ROUND(55.321,-2),ROUND(55.321,-3) FROM DUAL;
--					 50 				0 				100				 0 

4 精度不为整数:忽略小数

SELECT ROUND(5.4321,2.22222),ROUND(5.4321,2.99999) FROM DUAL;-- 5.43 5.43 

5 精度过高:显示最简形式

SELECT ROUND(5.4321,10) FROM DUAL;  -- 最简    5.4321

5 截断

TRUNC:对数值NUM进行截断,其中参数P决定截断精度

1 精度为0或者省略

SELECT TRUNC(4.54321,0),TRUNC(4.54321) FROM DUAL;  -- 4  4 

2 负数的截取

SELECT TRUNC(-1.4),TRUNC(-1.6) FROM DUAL;  -- -1  -1

3 精度为负数 -1 保留到十位 -2 保留到百位后面全部清0

SELECT TRUNC(45.321,-1),TRUNC(045.321,-2),TRUNC(055.321,-2),TRUNC(0055.321,-3) FROM DUAL;
--       40               0                         0               0

4 精度不为整数:忽略小数

SELECT TRUNC(5.4321,2.22222),TRUNC(5.4321,2.99999) FROM DUAL; -- 5.43 5.43 

四、日期型函数

1 日期函数的四舍五入和截断

1.1 省略精度

默认的精确到天 ,每天的12点为分界线

SELECT ROUND(SYSDATE,'DD'),ROUND(SYSDATE) FROM DUAL;  -- 此时已经过完十二点  2021/03/14  2021/03/14
1.2 年的界限

7月份为分界线 到七月份为下一年

ROUND(TO_DATE('20210630','YYYYMMDD'),'YYYY') FROM DUAL;          --2021/01/01
SELECT ROUND(TO_DATE('20210730','YYYYMMDD'),'YYYY') FROM DUAL;   --2022/01/01
1.3 月的界限

每月的16号为分界线 与月份无关

SELECT ROUND(TO_DATE('20210215','YYYYMMDD'),'MM') FROM DUAL;--2021/02/01
SELECT ROUND(TO_DATE('20210216','YYYYMMDD'),'MM') FROM DUAL;--2021/03/01
1.4 季的分界线

中间月份的16号 显示下个季度的1号 例如 :第一季度 1-3 分界线为2月16

SELECT ROUND(TO_DATE('20210331','YYYYMMDD'),'Q') FROM DUAL;   -- 2021/04/01 显示下个季度的1号
1.5 小时的界限

每个小时的30分为分界线

SELECT ROUND(TO_DATE('20210117 11:29:00','YYYYMMDD HH24:MI:SS'),'HH24') FROM DUAL; -- 11
SELECT ROUND(TO_DATE('20210117 11:30:00','YYYYMMDD HH24:MI:SS'),'HH24') FROM DUAL; -- 12 
SELECT ROUND(TO_DATE('20210117 11:31:00','YYYYMMDD HH24:MI:SS'),'HH24') FROM DUAL; -- 12
1.6 星期的界限

2 获取月份的差值

MONTHS_BETWEEN(D1,D2):求D1和D2之间差几个月 D1 > D2

1)计算从元旦到今天经过了几个月(整数月)--加上取整函数
SELECT CEIL(MONTHS_BETWEEN(SYSDATE,TO_DATE('20210101','YYYYMMDD'))) FROM DUAL;  

2)计算从元旦到今天经过了几个月(非整数月)
SELECT MONTHS_BETWEEN(SYSDATE,TO_DATE('20210101','YYYYMMDD')) FROM DUAL;

3)计算从今天到明年元旦还要等待几个月(整数月)
SELECT CEIL(MONTHS_BETWEEN(TO_DATE('20220101','YYYYMMDD'),SYSDATE)) FROM DUAL;

1)一般工作中使用到的情况是,给定两个月初或月末日期、或者两个DD相同的日期。如果给定的两个日期DD不相同,月份差会得到非整数,小数部分为剩余天数/31,这个规则无论针对哪一个月都是如此;
2)如果给定的两个日期DD不同,但是想要获得整数月,可以配合TRUNC函数或后续提到的获取月末日期函数使用;
3)如果两个日期的DD不同,但是都是月末日期,则获取的月份差将是整数;
4)需要特别注意,函数中录入的两个日期是有大小之分的(区别BETWEEN AND),一般晚的日期在前,早的日期在后,如此得到的结果便是正数,反之获得负数。如果不确定两个日期的大小,可搭配ABS()函数使用。

3 获取月末日期

LAST_DAY(D):获取指定日期对应的当月最后一天,即月末日期

默认带上时分秒 使用TRUNC函数 可以去掉时分秒

SELECT TRUNC(LAST_DAY(SYSDATE)),LAST_DAY(SYSDATE) FROM DUAL; -- 2021/03/31    2021/03/31 13:31:17

-- 查询某月份的最大天数
SELECT LAST_DAY(SYSDATE) FROM DUAL;
SELECT TO_CHAR(LAST_DAY(SYSDATE),'DD') FROM DUAL; -- 31

4 月份加减

ADD_MONTHS(D,N):在D日期的基础上加N个月 。 N 可正可负

SELECT SYSDATE,ADD_MONTHS(SYSDATE,2) FROM DUAL;
SELECT SYSDATE,ADD_MONTHS(TO_DATE('20210102','YYYYMMDD'),-2) FROM DUAL;

1 如果N是小数:小数部分没有意义

SELECT SYSDATE,ADD_MONTHS(SYSDATE,2.5) FROM DUAL;  --   2021/03/13 15:12:05   2021/05/13 15:12:05

2 如果D是月末:得到的是每个月的最后一天

SELECT SYSDATE,ADD_MONTHS(TO_DATE('20210131','YYYYMMDD'),-2) FROM DUAL; -- 2021/03/13 15:13:04  2020/11/30

5 获取下个周几

NEXT_DAY(D,W):给定日期D和星期W,获取D日期之后的下一个星期W(不是下个周的周几) 返回一个日期

SELECT NEXT_DAY(SYSDATE,'星期日') FROM DUAL;  --   星期日作为每一周的第一天 2021/03/13   2021/03/14 15:16:00
  • 给定日期获取下个周的星期N
SELECT TRUNC(TO_DATE('20210312','YYYYMMDD'),'IW')+6 FROM DUAL; -- 获取一周的最后一天 (星期日)
SELECT NEXT_DAY(TRUNC(TO_DATE('20210312','YYYYMMDD'),'IW')+6,'星期五'),TRUNC(TO_DATE('20210312','YYYYMMDD'),'IW')+6 FROM DUAL;   -- 2021/03/19   2021/03/14
-- 先找到20210312这一周的周一,加上六找到这一周的周日,在找到下周五

五、其他函数

1 条件取值

DECODE(EXPR,VALUE1,RESULT1,VALUE2,RESULT2,…,DEF_RESULT) : 类似于CASE WHEN THEN 只能判断等于某个条件

使用decode函数,职位是分析员的,工资+1000;职位是经理的,工资+800;职位是其它的,工资+400
-- DECODE() 函数  不建议用
SELECT ENAME,JOB,SAL,DECODE(JOB,'ANALYST',SAL+1000,'MANAGER',SAL+800,SAL+400) FROM EMP;

2 返回集合中第一个不为空的内容

COALESCE(c1,c2,c3,c4,…cn):返回括号中第一个非空表达式,如果都为空,则返回空

SELECT COALESCE(NULL,123,145) FROM DUAL; -- 123
SELECT COALESCE(NULL,NULL) FROM DUAL;   -- 空

3 空值的赋值

NVL(EXPR,VALUE):如果EXPR是空,返回一个VALUE,如果EXPR不为空,返回EXPR本身

NVL2(EXPR1,EXPR2,EXPR3):expr1不为NULL,返回expr2;expr1为NULL,返回expr3

SELECT NVL2(SAL+COMM,SAL,SAL+COMM)FROM EMP;

4 去重

DISTINCT:紧跟SELECT后面

SELECT DISTINCT COL_LIST FROM TB_NAME … 对COL_LIST范围内的字段进行去重

获取各部门的各岗位
SELECT DISTINCT JOB,DEPTNO FROM EMP ;
SELECT DISTINCT DEPTNO,JOB FROM EMP ;
SELECT DEPTNO,JOB FROM EMP GROUP BY DEPTNO,JOB;

你可能感兴趣的:(数据库,sql)