想象一下,你正在处理一个包含百万条数据的报表,老板要求你在半小时内完成分析。这时,Oracle函数就像是你的"瑞士军刀",能帮你快速切割、处理数据。无论你是刚入门的新手,还是经验丰富的老鸟,这些函数都能让你的SQL语句如虎添翼!
-- CONCAT:字符串拼接
SELECT CONCAT('Hello', ' World') FROM dual; -- 结果:Hello World
-- SUBSTR:截取子串
SELECT SUBSTR('Oracle大师课', 4, 2) FROM dual; -- 结果:大师
-- LENGTH:获取长度
SELECT LENGTH('数据库') FROM dual; -- 结果:3
-- REPLACE:文本替换
SELECT REPLACE('我喜欢MySQL', 'MySQL', 'Oracle') FROM dual; -- 结果:我喜欢Oracle
职场小故事:小王用REPLACE
函数一键修改了5000条错误的产品描述,省去了3小时手工修改时间!
-- REGEXP_REPLACE:正则替换
SELECT REGEXP_REPLACE('电话:138-1234-5678', '\D', '') FROM dual; -- 结果:13812345678
-- INSTR:查找位置
SELECT INSTR('寻找隐藏的宝藏', '宝藏') FROM dual; -- 结果:6
-- ROUND:四舍五入
SELECT ROUND(123.4567, 2) FROM dual; -- 结果:123.46
--CEIL:向上取整
SELECT CEIL(15.3) FROM dual; -- 返回 16
--FLOOR:向下取整
SELECT FLOOR(15.7) FROM dual; -- 返回 15
-- TRUNC:截断数字
SELECT TRUNC(123.4567, 2) FROM dual; -- 结果:123.45
-- MOD:取余数
SELECT MOD(15, 4) FROM dual; -- 结果:3
-- 标准差计算
SELECT STDDEV(salary) FROM employees;
-- 百分比排行
SELECT employee_name,
PERCENT_RANK() OVER (ORDER BY salary DESC) AS "薪资排名百分比"
FROM employees;
-- 获取当前日期
SELECT SYSDATE FROM dual; -- 结果:2023-08-15 14:30:22
-- 日期加减
SELECT SYSDATE + 7 FROM dual; -- 7天后
-- 月份差计算
SELECT MONTHS_BETWEEN('2023-12-31', '2023-08-15') FROM dual; -- 结果:4.516...
-- 季度提取
SELECT TO_CHAR(SYSDATE, 'Q') FROM dual; -- 当前季度
-- 工作日计算(需自定义函数)
CREATE OR REPLACE FUNCTION WORK_DAYS(start_date IN DATE, end_date IN DATE)
RETURN NUMBER IS
/* 省略实现代码 */
END;
-- 数字转字符串
SELECT TO_CHAR(1234.56, 'L9,999.99') FROM dual; -- 结果:¥1,234.56
-- 字符串转日期
SELECT TO_DATE('2023年08月15日', 'YYYY"年"MM"月"DD"日"') FROM dual;
-- 智能转换
SELECT CAST('123.45' AS NUMBER(5,2)) FROM dual; -- 结果:123.45
-- 字符集转换
SELECT CONVERT('甲骨文', 'UTF8', 'ZHS16GBK') FROM dual;
-- BASE64编码
SELECT UTL_ENCODE.BASE64_ENCODE('secret') FROM dual;
-- 部门薪资排名
SELECT employee_name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
-- 移动平均值
SELECT sales_date, amount,
AVG(amount) OVER (ORDER BY sales_date ROWS 2 PRECEDING) AS 3day_avg
FROM daily_sales;
-- 行列转换
SELECT *
FROM (SELECT department, job_title, salary FROM employees)
PIVOT (AVG(salary) FOR job_title IN ('经理' AS mgr, '工程师' AS eng));
-- NVL:空值替换
SELECT NVL(commission_pct, 0) FROM employees;
-- COALESCE:返回第一个非空值
SELECT COALESCE(middle_name, first_name, '无名氏') FROM customers;
-- 用户身份验证
SELECT SYS_CONTEXT('USERENV', 'SESSION_USER') FROM dual;
-- 数据库版本
SELECT * FROM v$version;
函数索引:为常用函数表达式创建索引
CREATE INDEX idx_upper_name ON employees(UPPER(last_name));
避免陷阱:在WHERE子句中慎用函数,可能导致索引失效
-- 不好的写法(索引失效)
SELECT * FROM orders WHERE TO_CHAR(order_date, 'YYYY-MM') = '2023-08';
-- 优化写法
SELECT * FROM orders
WHERE order_date >= TO_DATE('2023-08-01', 'YYYY-MM-DD')
AND order_date < TO_DATE('2023-09-01', 'YYYY-MM-DD');
场景:生成月度销售报告,要求:
SELECT
region,
product_category,
TO_CHAR(sales_amount, 'L999,999,999.99') AS "销售额",
ROUND((sales_amount - LAG(sales_amount, 1) OVER (PARTITION BY region, product_category ORDER BY month)) /
LAG(sales_amount, 1) OVER (PARTITION BY region, product_category ORDER BY month) * 100, 2) || '%' AS "环比增长",
CASE WHEN ABS(sales_amount - AVG(sales_amount) OVER (PARTITION BY region, product_category)) >
3 * STDDEV(sales_amount) OVER (PARTITION BY region, product_category)
THEN '异常' ELSE '正常' END AS "状态"
FROM monthly_sales
WHERE year = 2023
ORDER BY region, product_category, month;
记住,函数不是用来死记硬背的,而是解决问题的工具。当你遇到数据处理难题时,不妨停下来想想:“有没有一个函数可以帮我搞定这个?” 久而久之,你就会发现,自己已经成长为同事眼中的"Oracle函数百科全书"了!