关键词:Oracle高级SQL、JOIN查询、子查询、GROUP BY、聚合函数、ROW_NUMBER、LAG/LEAD、CASE WHEN、DECODE
在实际业务开发中,我们经常需要从多个表中提取数据、进行复杂计算和统计。Oracle 提供了强大的 SQL 功能支持这些操作,包括:
本文将带你系统掌握 Oracle 中的 高级 SQL 查询技巧,并提供每个知识点的 完整示例代码,适合初学者学习提升,也适合中级开发者查漏补缺。
内连接只返回两个表中匹配的记录。
SELECT e.employee_id, e.first_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;
类型 | 描述 |
---|---|
LEFT JOIN | 返回左表所有记录 + 右表匹配记录 |
RIGHT JOIN | 返回右表所有记录 + 左表匹配记录 |
FULL JOIN | 返回两表所有记录 |
SELECT e.employee_id, e.first_name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;
不带条件的连接,结果为两个表行数的乘积。
SELECT e.first_name, j.job_title
FROM employees e
CROSS JOIN jobs j;
一个表与自身连接,常用于树形结构数据(如员工与上级)。
SELECT e.first_name AS employee, m.first_name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.employee_id;
类型 | 示例 | 说明 |
---|---|---|
标量子查询 | (SELECT salary FROM employees WHERE employee_id = 100) |
返回单个值 |
列子查询 | WHERE department_id IN (SELECT department_id FROM departments WHERE location_id > 1000) |
返回一列 |
行子查询 | WHERE (first_name, last_name) = (SELECT first_name, last_name FROM employees WHERE employee_id = 100) |
返回一行 |
表子查询 | FROM (SELECT * FROM employees WHERE salary > 5000) |
返回一张临时表 |
SELECT first_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
常用聚合函数:
COUNT()
:计数SUM()
:求和AVG()
:平均值MIN()
/ MAX()
:最小最大值SELECT department_id, COUNT(*) AS employee_count, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
-- 查找员工数大于5的部门
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
函数 | 说明 |
---|---|
SUBSTR(str, start, length) |
截取字符串 |
INSTR(str, substr) |
查找子串位置 |
UPPER() , LOWER() |
大小写转换 |
TRIM() |
去除空格 |
SELECT SUBSTR(email, 1, 5) AS short_email
FROM employees;
函数 | 说明 |
---|---|
SYSDATE |
当前时间 |
TO_DATE() |
将字符串转为日期 |
ADD_MONTHS(date, n) |
加减月份 |
MONTHS_BETWEEN(date1, date2) |
两个日期之间的月份数 |
SELECT first_name, hire_date
FROM employees
WHERE hire_date < ADD_MONTHS(SYSDATE, -6);
SELECT first_name, salary,
CASE
WHEN salary < 5000 THEN '低薪'
WHEN salary BETWEEN 5000 AND 8000 THEN '中薪'
ELSE '高薪'
END AS salary_level
FROM employees;
SELECT job_id,
DECODE(job_id,
'IT_PROG', '程序员',
'SA_REP', '销售代表',
'HR', '人力资源',
'未知职位') AS job_desc
FROM employees;
分析函数是 Oracle 的一大亮点,适用于报表、排名、趋势分析等场景。
函数 | 说明 |
---|---|
ROW_NUMBER() |
排序后生成唯一序号 |
RANK() |
相同值并列,跳过后续排名 |
DENSE_RANK() |
相同值并列,不跳过后续排名 |
LAG(col, n) |
获取当前行之前第 n 行的 col 值 |
LEAD(col, n) |
获取当前行之后第 n 行的 col 值 |
SELECT first_name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num,
RANK() OVER (ORDER BY salary DESC) AS rank_num,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank_num
FROM employees;
SELECT first_name, salary,
LAG(salary, 1) OVER (ORDER BY salary DESC) AS prev_salary
FROM employees;
通过本文的学习,你应该已经掌握了以下内容:
模块 | 技能点 |
---|---|
多表连接 | INNER JOIN、LEFT JOIN、自连接、CROSS JOIN |
子查询 | 标量、列、行、表子查询,结合 HAVING 使用 |
聚合函数 | SUM、AVG、COUNT,GROUP BY 与 HAVING |
字符处理 | SUBSTR、INSTR、TRIM、UPPER、LOWER |
日期函数 | SYSDATE、TO_DATE、ADD_MONTHS、MONTHS_BETWEEN |
条件判断 | CASE WHEN、DECODE |
分析函数 | ROW_NUMBER、RANK、LAG、LEAD |
这些技能是你成为 Oracle 数据库高手的必备基础。建议你将文中示例复制到本地数据库环境中运行练习,加深理解。