三、Oracle 函数


一、字符函数

函数说明
ASCII返回对应字符的十进制值
CHR给出十进制返回字符
CONCAT拼接两个字符串,与 || 相同
INITCAT将字符串的 第一个字母变为大写
INSTR找出 某个字符串的 位置
INSTRB找出 某个字符串的 位置 和 字节数
LENGTH以 字符 给出 字符串的长度
LENGTHB以 字节 给出 字符串的长度
LOWER将字符串 转换成小写
LPAD使用 指定的字符 在字符的 左边填充
LTRIM左边裁剪 掉 指定的字符
RPAD使用 指定的字符 在字符的 右边填充
RTRIM右边裁剪 掉 指定的字符
REPLACE执行字符串 搜索 和 替换
SUBSTR取字符串的 子串
SUBSTRB取字符串的 子串(以字节)
SOUNDEX返回一个 同音字符串
TRANSLATE执行字符串 搜索 和 替换
TRIM裁剪 掉 前面 或 后面 的字符串
UPPER将字符串 转换成大写

1. length() 求字符串长度

-- dual 伪表
select length('ABCD') from dual; 
-- 4

2. substr() 求字符串的子串

-- 第 2 位开始,截取 2 位
select substr('ABCD', 2, 2) from dual; 
-- BC

3. concat() 字符串拼接

select concat('ABC', 'D') from dual;
-- ABCD

select concat( concat('ABC', 'D'), 'EF') from dual;
-- ABCDEF

-- 模糊查询
select * 
from `user` 
where name like CONCAT(CONCAT('%', #{name}), '%');

  • Oracle 也可以用 || 对字符串进行拼接
select 'ABC'||'D' from dual; 

SELECT '序列=' || demo_seq.nextval FROM DUAL;

4. wm_concat() 分组字符串拼接

SELECT 
	t1.NAME AS '区域', t2.NAME AS '地址' 
FROM T_AREA t1 
LEFT JOIN T_ADDRESS t2 ON t2.AREAID = t1.ID;

在这里插入图片描述


  • wm_concat() 分组拼接函数
SELECT 
	t1.NAME AS '区域', wm_concat(t2.NAME) AS '地址' 
FROM T_AREA t1 
LEFT JOIN T_ADDRESS t2 ON t2.AREAID = t1.ID
GROUP BY t1.NAME;

在这里插入图片描述


5. lpad() 填充字符串的左边

-- 长度限定3位,不够补0,超过截取。
SELECT
	LPAD( 1, 3, '0' ) AS CODE 
FROM
	DUAL;
-- 001
SELECT
	LPAD( 12, 3, '0' ) AS CODE 
FROM
	DUAL;
-- 012
SELECT
	LPAD( 123, 3, '0' ) AS CODE 
FROM
	DUAL;
-- 123
SELECT
	LPAD( 1234, 3, '0' ) AS CODE 
FROM
	DUAL;
-- 123

SELECT
	LPAD( 99, 5, 'A' ) AS CODE 
FROM
	DUAL;
-- AAA99

SELECT
	100 || TO_CHAR( SYSDATE, 'YYMMDD' ) || LPAD( SEQ_ID.NEXTVAL, 11, '0' ) ID 
FROM
	DUAL

6. 数据脱敏

CASE WHEN length(name) > 2 
THEN substr(name, 1, 1) || '*' || substr(name, length(name), 1) 
ELSE '*' || substr(name, length(name), 1) 
END

二、数值函数

函数说明
ABS(value)绝对值
CEIL(value)大于或等于 value 的最小整数
COS(value)余弦
COSH(value)反余弦
EXP(value)e 的 value 次幂
FLOOR(value)小于或等于 value 的最大整数
LN(value)value 的自然对数
LOG(value)value 的以 10 为底的对数
MOD(value,divisor)求模
POWER(value,exponent)value 的 exponent 次幂
ROUND(value,precision)按 precision 精度 4 舍 5 入
SIGN(value)value 为正返回 1,为负返回 -1,为零返回 0
SIN(value)余弦
SINH(value)反余弦
SQRT(value)value 的平方根
TAN(value)正切
TANH(value)反正切
TRUNC(value,precision)按照 precision 截取 value
VSIZE(value)返回 value 在 Oracle 的存储空间大小

1. round() 四舍五入函数

select round(100.456) from dual;
-- 100 

select round(100.567) from dual;
-- 101 

select round(100.567, 2) from dual;
-- 100.57 

2. trunc() 截取函数

  • 日期 trunc() 按月截取,得到当月第一天
  1. mm/MM:代表月
  2. mi:代表分钟
select trunc(100.456) from dual;
-- 100 
  
select trunc(100.567) from dual;
-- 100  

select trunc(100.567, 2) from dual;
-- 100.56 

3. mod() 取模

-- 10 % 3 = 1
select mod(10,3) from dual; 
-- 1

4. sign() 正负数

SELECT SIGN(100) sign_1, SIGN(0) sign_2, SIGN(-100) sign_3, SIGN(null) sign_4
FROM DUAL;
-- sign_1: 大于0为1 
-- sign_2: 等于0为0
-- sign_3: 小于0为-1
-- sign_4: 为null

5. random() 随机值

SELECT dbms_random.value FROM DUAL;
-- 0.80279094682468220172572693232587538125

SELECT t.*
FROM (
     SELECT un.*, ROWNUM AS rm
     FROM (
              SELECT 'wy' AS name, 18 AS age
              FROM DUAL
              UNION ALL
              SELECT 'wyb' AS name, 20 AS age
              FROM DUAL
              UNION ALL
              SELECT 'qs' AS name, 26 AS age
              FROM DUAL
              UNION ALL
              SELECT 'qs_home' AS name, 28 AS age
              FROM DUAL
    ) un
    -- 随机值排序。
    ORDER BY dbms_random.value
) t WHERE t.rm <= 2;

三、日期函数

函数说明
ADD_MONTHS在日期 date 上增加 count 个月
GREATEST(date1, date2, . . .)从日期列表中选出 最晚的日期
LAST_DAY( date )返回日期 date 所在月的最后一天
LEAST( date1, date2, . . .)从日期列表中选出 最早的日期
MONTHS_BETWEEN(date2, date1)给出 date2 - date1 的月数(可以是小数)
NEXT_DAY( date, ‘day’)给出日期 date 之后下一天的日期,这里的 day 为星期。如:MONDAY、Tuesday 等
NEW_TIME(date, ‘this’, ‘other’)给出在 this 时区 = other 时区 的日期和时间
ROUND(date,’format’)未指定 format 时,如果日期中的时间在中午之前,则将日期中的时间截断为 12 A.M(午夜,一天的开始)否则进到第二天
TRUNC(date,’format’)未指定 format 时,将日期截为 12 A.M(午夜,一天的开始)

1. sysdate 系统日期

-- 用`sysdate`这个系统变量来获取当前日期和时间 
select sysdate from dual;

-- 减去2分钟
SELECT sysdate, sysdate - 1 / 24 / 30
FROM DUAL;
-- 2022-04-06 17:08:31	2022-04-06 17:06:31

2. add_months() 加指定个月

-- 当前日期`+2`个月 
select add_months(sysdate, 2) from dual;

-- 当前日期`-2`个月
select add_months(sysdate, -2) from dual; 

3. last_day() 当月最后一天

select last_day(sysdate) from dual;

4. trunc() 日期截取

-- 按日截取
select TRUNC(sysdate) from dual;

-- 当年第一天
select TRUNC(sysdate, 'yyyy') from dual;

-- 当月第一天
select TRUNC(sysdate, 'mm') from dual;

-- 按小时截取
select TRUNC(sysdate, 'hh') from dual;

-- 按分钟截取
select TRUNC(sysdate, 'mi') from dual;

select sysdate from dual;
-- 2022-04-06 17:04:05

select trunc(sysdate) from dual;
-- 2022-04-06 00:00:00

select trunc(sysdate, 'MM') from dual;
-- 2022-04-01 00:00:00
select trunc(sysdate, 'mm') from dual;
-- 2022-04-01 00:00:00

select trunc(sysdate, 'mi') from dual;
-- 2022-04-06 17:05:00

5. to_timestamp() 字符串转日期

to_timestamp('2020-01-20 14:20:30', 'yyyy-MM-dd hh24:mi:ss:ff');

四、转换函数

-- TIMESTAMP 转 DATE
SELECT 
	TO_DATE(TO_CHAR(SYSDATE, 'yyyy-MM-dd HH24:mi:ss'), 'yyyy-MM-dd HH24:mi:ss')
FROM DUAL;

-- TIMESTAMP 转 DATE
SELECT CAST(SYSDATE AS DATE)
FROM DUAL;

函数说明
CHARTOROWID将字符转换到 Rowid 类型
CONVERT转换一个字符节 到 另外一个字符节
HEXTORAW转换十六进制 到 Raw 类型
RAWTOHEX转换 Raw 到 十六进制
ROWIDTOCHAR转换 ROWID 到 字符
TO_CHAR转换日期格式 到 字符串
TO_DATE按照指定的格式将 字符串 转换到 日期型
TO_MULTIBYTE把 单字节字符 转换到 多字节
TO_NUMBER将 数字字串 转换到 数字
TO_SINGLE_BYTE转换 多字节 到 单字节

1. to_char() 日期转字符串

select TO_CHAR(sysdate, 'yyyy-mm-dd') from dual;

select TO_CHAR(sysdate, 'yyyy-mm-dd hh:mi:ss') from dual;

select TO_CHAR(sysdate, 'yyyy')||'年' 
	|| TO_CHAR(sysdate, 'mm')||'月'
	|| TO_CHAR(sysdate, 'dd')||'日' 
from dual;

SELECT to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss'),
       to_char(null, 'yyyy-MM-dd HH24:mi:ss')
FROM DUAL;
-- 2022-04-06 17:11:25	null

SELECT TO_CHAR(
	(select date from MESSAGE_INFO where bh = '1480'), 
	'YY-MM-DD HH24:MI:SS'
) FROM DUAL;

SELECT to_date('2021-12-31 10:59:49', 'yyyy-MM-dd HH24:mi:ss'),
       sysdate - to_date('2021-12-31 10:59:49', 'yyyy-MM-dd HH24:mi:ss')
FROM DUAL;
-- 2021-12-31 10:59:49	96.25890046296296296296296296296296296296

SELECT to_date(null, 'yyyy-MM-dd HH24:mi:ss'),
       sysdate - to_date(null, 'yyyy-MM-dd HH24:mi:ss'),
       to_date(null, 'yyyy-MM-dd HH24:mi:ss') - 1
FROM DUAL;

2. to_date() 字符串转日期

select TO_DATE('2017-01-01', 'yyyy-mm-dd') from dual;

3. to_number() 字符串转数字

select to_number('100') from dual;

-- '1024' 数字转字符串
select TO_CHAR(1024) from dual;

--110
select '100'+10 from dual;

--'1000'
select '100'||0 from dual; 
select to_number(substr('123456', 4)) from dual;
-- 456

-- 计算年龄
select to_number(to_char(sysdate, 'yyyy') - to_char('生日, 'yyyy')) from dual;

五、其它函数

<![CDATA[ <= ]]>

-- 不等于
NVL(flag, '0') <> '1';

-- 序列
select demo_seq.nextval from dual;

1. nvl() 判断 NULL

  • 空值处理函数
  1. 用法:NVL(检测的值, 如果为 null 的值)
  2. NVL(E1, E2):如果 E1 为 null,则函数返回 E2,否则返回 E1 本身

  • 需求:显示价格表中 业主类型ID 为 1 的价格记录,如果上限值为 NULL 则显示 9999999
select PRICE, MINNUM, NVL(MAXNUM, 9999999) 
from T_PRICETABLE 
where OWNERTYPEID = 1;
SELECT nvl(null, 0) nvl1, nvl(100, 0) nvl2
FROM DUAL;
-- nvl1: IS NULL ? 0
-- nvl2: 100 != null ? 100 : 0

-- 0
select NVL(NULL,0) from dual;
-- 100
select NVL(100,0) from dual;

case when 
	nvl(money, 0.00) != 0.00 and 10 >  nvl(money, 0.00) 
then 1 
else 0 
end money

case when 
	state in (1, 4, 6)  
then 'A' 
else 'B'
end state	

2. nvl2() 三元表达式

  • 空值处理函数
  1. 用法:NVL2(检测的值, 如果不为 null 的值, 如果为 null 的值)
  2. NVL2(E1, E2, E3):如果 E1 为 null,则函数返回 E3,若 E1 不为 null,则返回 E2

  • 需求:显示价格表中 业主类型ID 为 1 的价格记录,如果上限值为 NULL 显示 不限
select PRICE, MINNUM, NVL2(MAXNUM, to_char(MAXNUM), '不限') 
from T_PRICETABLE 
where OWNERTYPEID = 1;
SELECT nvl2(null, 10, 0) nvl21, nvl2(100, 10, 0) nvl22
FROM DUAL;
-- nvl21: IS NULL ? 0 : 10
-- nvl22: 100 != null ? 10 : 0

3. decode() 多级判断

  1. 写法:decode(条件, 值1, 翻译值1, 值2, 翻译值2, 值…n, 翻译值…n, 缺省值)
  2. 根据条件返回相应值,没有匹配值,也没有缺省值,返回 null

  • 需求:显示下列信息(不要关联查询业主类型表,直接判断 1 2 3 的值)
-- 只返回第一个对应值   
select name, decode(ownertypeid, 1, '居民', 2, '行政事业单位', 3, '商 业') as '类型' 
from T_OWNERS;

# `SQL-1999` 的语法`case when then`语句来实现
select name, ( 
	case ownertypeid
	when 1 then '居民'
   	when 2 then '行政事业单位'
   	when 3 then '商业'
   	else '其它'
   	end 
) from T_OWNERS;   

select name, ( 
	case
	when ownertypeid = 1 then '居民'
	when ownertypeid = 2 then '行政事业'
	when ownertypeid = 3 then '商业'
	end 
) from T_OWNERS;   

SELECT decode(10, 10, 100, 0) decode1, decode(10, 11, 100, 0) decode2
FROM DUAL;
-- decode1: 10 == 10 ? 100 : 0
-- decode2: 10 == 11 ? 100 : 0

decode(
	nvl(
    	sign(
        	to_date(
        		to_char(bbh, 'yyyy-MM-dd HH24:mi:ss'), 
        		'yyyy-MM-dd HH24:mi:ss'
        	) - sysdate
        ), 
        1
  	), 
  	1, price1, price2
) AS price,
    
decode(
	length(id_card), 
	18, (substr(id_card, 1, 3) || '***********' || substr(id_card, 15, 18)),
	15, (substr(id_card, 1, 3) || '********' || substr(id_card, 12, 15))
) id_card,
			
decode(
	gender, 
	'0', '未知的性别', 
	'1', '男性',
	'2', '女性',
	'9', '未说明的性别'
) gender,

decode(
	isleaf, 
	1,
	'是',
	'否'
) isleaf,

4. distinct 去重

-- 对两列都去重 
distinct name1, name2;    

5. listagg() 分组字符串拼接

listagg(
	(
		'[' || decode(t.xxsfyd, '0', '未读', '1', '已读') || ']' || c.jc
	),
	','
) within group (order by t.xxsfyd, c.jc) xxsfyd,
-- [未读]张三,[已读]李四,[未读]王五

6. userenv() 用户环境

SELECT USERENV('LANGUAGE') FROM DUAL;

-- 用户`ID`
SELECT USERENV('SCHEMAID') AS "用名ID" FROM DUAL;

参数功能
CLINET_INFO返回最高可达 64 个字节存储的用户会话信息,可由应用程序使用 DBMS_APPLICATION_INFO 包
ENTRYID返回当前审计条目编号。审计的 EntryID 序列,细粒度的审计记录和定期审计记录之间共享。在分布式 SQL 语句不能使用这个属性
ISDBA如果用户已经被认证为 DBA,或者是通过操作系统或口令文件具有 DBA 特权的,返回 true,否则返回 false
LANG返回 ISO 缩写语言名称,一个比现有的 语言参数 较短的形式
LNAGUAGE返回数据库当前会话的语言、地域和字符集
SESSIONID返回审计会话标识符。在分布式 SQL 语句不能指定此参数
SID返回数据库 会话 ID
TERMINA返回当前会话的终端操作系统的标识符。在分布式 SQL 语句,此参数返回了标识符为本地会话。在分布式环境中,此参数只支持远程 SELECT 语句,不用于远程 INSERT、 UPDATE 或 DELETE 操作

六、行列转换

  • 需求:按月份统计 2012 年各个地区的水费
-- 统计`2012`年各个地区的水费总和
select 
	( select name from T_AREA where id = areaid ) '区域',
	sum(money) 
from T_ACCOUNT 
where year = '2012' 
group by areaid; 

select (select name from T_AREA where id= areaid ) '区域',
	-- 查询一月水费,其他为0
    sum( case when month='01' then money else 0 end ) '一月', 
    -- 查询二月水费,其他为0
    sum( case when month='02' then money else 0 end ) '二月', 
    sum( case when month='03' then money else 0 end ) '三月',
    sum( case when month='04' then money else 0 end ) '四月',
    sum( case when month='05' then money else 0 end ) '五月',
    sum( case when month='06' then money else 0 end ) '六月',
    sum( case when month='07' then money else 0 end ) '七月',
    sum( case when month='08' then money else 0 end ) '八月',
    sum( case when month='09' then money else 0 end ) '九月',
    sum( case when month='10' then money else 0 end ) '十月',
    sum( case when month='11' then money else 0 end ) '十一月',
    sum( case when month='12' then money else 0 end ) '十二月'
from T_ACCOUNT 
where year = '2012' 
group by areaid;

  • 需求:按季度统计 2012 年各个地区的水费
select ( select name from T_AREA where id = areaid ) '区域',
	sum( case when month >= '01' and month <= '03' then money else 0 end ) '第一季度',
	sum( case when month >= '04' and month <= '06' then money else 0 end ) '第二季度',
	sum( case when month >= '07' and month <= '09' then money else 0 end ) '第三季度',
	sum( case when month >= '10' and month <= '12' then money else 0 end ) '第四季度'
from T_ACCOUNT 
where year = '2012' 
group by areaid

七、分析函数

1. RANK() 相同值排名相同,排名跳跃

  • 需求:对 T_ACCOUNT 表的 usenum 字段进行排序,相同的值排名相同,排名跳跃
select 
	rank() over( order by usenum desc ) '排名', 
	usenum 
from T_ACCOUNT;
select
	rank() over(partition by '42502763900' order by '11111362' desc) ranknum,
	t.*       
from USER t;  

2. DENSE_RANK() 相同值排名相同,排名连续

  • 需求:对 T_ACCOUNT 表的 usenum 字段进行排序,相同的值排名相同,排名连续
select 
	dense_rank() over( order by usenum desc ) '排名', 
	usenum 
from T_ACCOUNT;

3. ROW_NUMBER() 连续的排名,无论值是否相等

  • 需求:对 T_ACCOUNT 表的 usenum 字段进行排序,返回连续的排名,无论值是否相等
select 
	row_number() over( order by usenum desc ) '排名', 
	usenum 
from T_ACCOUNT; 

4. row_number()【实现分页】

  • 用 row_number() 分析函数,实现的分页查询相对三层嵌套子查询要简单的多
select * 
from ( select row_number() over( order by usenum desc ) rownumber, usenum from T_ACCOUNT )
where rownumber > 10 
  and rownumber <= 20;    

八、集合运算

  • 集合运算 就是将 两个 或者 多个 结果集,组合成为一个结果集
函数名称说明
UNION ALL并集返回各个查询的所有记录,包括重复记录
UNION并集返回各个查询的所有记录,不包括重复记录
INTERSECT交集返回两个查询 共有的记录。
MINUS差集返回第一个查询检索出的记录 减去 第二个查询检索出的记录之后 剩余 的记录

1. 并集运算

  • UNION ALL:不去掉重复记录
select * from t_owners where id <= 7
union all
select * from t_owners where id >= 5;
-- 1234567 
-- 56789
-- 1234567 + 56789

  • UNION:去掉重复记录
select * from t_owners where id <= 7
union
select * from t_owners where id >= 5;
-- 123456789

2. 交集运算

select * from t_owners where id <= 7 
intersect
select * from t_owners where id >= 5;
-- 567

3. 差集运算

select * from t_owners where id <= 7 
minus
select * from t_owners where id >= 5;
-- 1234

4. minus 【实现分页】

  • 用 minus 运算符来实现分页
-- 11、12、13、14、15、...20
select rownum,t.* from T_ACCOUNT t where rownum<=20 
minus
select rownum,t.* from T_ACCOUNT t where rownum<=10

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑士梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值