SQL高级语法与函数详解(Oracle/PostgreSQL/MySQL)

AI 概述
一、窗口函数(Window Functions)1. 核心语法对比2. 常用窗口函数及用途二、递归查询(Recursive CTE)1. 语法对比三、存储过程(Stored Procedure)1. 语法对比四、执行计划分析(Execution Plan)1. 查看方法对比五、扩展功能实战1. Oracle Data Guard(高可用灾备)2. PostgreSQL PostGIS(地理数...
目录
文章目录隐藏
  1. 一、窗口函数(Window Functions)
  2. 二、递归查询(Recursive CTE)
  3. 三、存储过程(Stored Procedure)
  4. 四、执行计划分析(Execution Plan)
  5. 五、扩展功能实战
  6. 六、核心差异总结

SQL 高级语法与函数详解(Oracle/PostgreSQL/MySQL)

一、窗口函数(Window Functions)

窗口函数用于对结果集的子集(窗口)进行计算,保留原始行的同时生成聚合或排序结果。

1. 核心语法对比

数据库
语法结构
过滤方式
支持版本
Oracle 函数名() OVER (PARTITION BY 列 ORDER BY 列 [ROWS/RANGE ...])
可直接在WHERE过滤
所有版本
PostgreSQL
语法同 Oracle,需嵌套子查询过滤结果(如SELECT * FROM (SELECT ...) WHERE rank <= 3
需子查询
所有版本
MySQL
语法同 PostgreSQL,但仅支持ROWS窗口范围
需子查询
MySQL 8.0+

2. 常用窗口函数及用途

函数
作用
Oracle 示例
PostgreSQL/MySQL 示例
ROW_NUMBER()
生成唯一行号(无并列)
ROW_NUMBER() OVER (ORDER BY salary)
同 Oracle
RANK()
排名(并列后跳号)
RANK() OVER (PARTITION BY dept_id ORDER BY salary)
同 Oracle
DENSE_RANK()
排名(并列后不跳号)
DENSE_RANK() OVER (ORDER BY sales)
同 Oracle
LEAD(列, n)
获取当前行后第 n 行的值
LEAD(salary, 1) OVER (ORDER BY emp_id)
同 Oracle
LAG(列, n)
获取当前行前第 n 行的值
LAG(salary, 1) OVER (ORDER BY emp_id)
同 Oracle
SUM()/AVG()
累计求和/平均
SUM(salary) OVER (PARTITION BY dept_id)
同 Oracle

示例:部门内薪资累计和

-- 三库通用
SELECT
  emp_id,
  dept_id,
  salary,
  SUM(salary) OVER (PARTITIONBY dept_id ORDERBY emp_id) AS cumulative_sum
FROM employees;

差异总结

Oracle 允许直接在WHERE子句中使用窗口函数结果,而 PostgreSQL/MySQL 需嵌套查询(如SELECT * FROM (SELECT ...) WHERE rank <= 3
MySQL 8.0 以下版本不支持窗口函数。

二、递归查询(Recursive CTE)

递归查询用于处理树形或层级数据(如组织结构、分类树)。

1. 语法对比

数据库
语法结构
终止条件控制
默认递归深度限制
Oracle WITH 别名 AS (初始查询 UNION ALL 递归查询) SELECT ...
自动检测循环
无限制
PostgreSQL WITH RECURSIVE 别名 AS (初始查询 UNION ALL 递归查询) SELECT ...
需手动控制(如LIMIT
无限制
MySQL
语法同 PostgreSQL,需显式声明RECURSIVE
需手动控制
1000 层(可调)

示例:查询员工层级关系

-- Oracle
WITH org_tree AS (
SELECT emp_id, name, 1AS level FROM employees WHERE manager_id ISNULL
UNIONALL
SELECT e.emp_id, e.name, ot.level +1
FROM employees e
JOIN org_tree ot ON e.manager_id = ot.emp_id
)
SELECT*FROM org_tree;

-- PostgreSQL/MySQL(需添加 RECURSIVE 关键字)
WITHRECURSIVE org_tree AS (
SELECT emp_id, name, 1AS level FROM employees WHERE manager_id ISNULL
UNIONALL
SELECT e.emp_id, e.name, ot.level +1
FROM employees e
JOIN org_tree ot ON e.manager_id = ot.emp_id
)
SELECT*FROM org_tree;

差异总结

Oracle 使用CONNECT BY语法(START WITH ... CONNECT BY PRIOR)实现递归查询,而 PostgreSQL/MySQL 使用标准WITH RECURSIVE
MySQL 需调整cte_max_recursion_depth参数以突破默认递归深度限制。

三、存储过程(Stored Procedure)

存储过程用于封装复杂业务逻辑,支持事务控制与异常处理。

1. 语法对比

功能
Oracle (PL/SQL)
PostgreSQL (PL/pgSQL)
MySQL
参数传递 IN

OUTIN OUT
IN

OUTINOUT
IN

OUTINOUT
自增 ID 生成
依赖序列(SEQUENCE
SERIAL

类型自动生成
AUTO_INCREMENT

字段
异常处理 EXCEPTION WHEN ... THEN ... EXCEPTION WHEN ... THEN ... DECLARE ... HANDLER FOR ...
调试工具
SQL Developer 内置调试器
pgAdmin4 插件
第三方工具(如 dbForge)

示例:插入员工并返回 ID

-- Oracle(需创建序列)
CREATE SEQUENCE employees_seq STARTWITH100;
CREATEOR REPLACE PROCEDURE add_employee (
  p_name IN VARCHAR2,
  p_dept_id IN NUMBER,
  p_emp_id OUT NUMBER
) AS
BEGIN
INSERTINTO employees (emp_id, name, dept_id)
VALUES (employees_seq.NEXTVAL, p_name, p_dept_id)
  RETURNING emp_id INTO p_emp_id;
END;
/

-- PostgreSQL(使用 SERIAL 自增)
CREATEOR REPLACE FUNCTION add_employee(
  p_name VARCHAR,
  p_dept_id INT,
OUT p_emp_id INT
) LANGUAGE plpgsql AS $$
BEGIN
INSERTINTO employees (name, dept_id)
VALUES (p_name, p_dept_id)
  RETURNING emp_id INTO p_emp_id;
END;
$$;

-- MySQL(使用 AUTO_INCREMENT)
DELIMITER $$
CREATEPROCEDURE add_employee(
IN p_name VARCHAR(50),
IN p_dept_id INT,
OUT p_emp_id INT
)
BEGIN
INSERTINTO employees (name, dept_id) VALUES (p_name, p_dept_id);
SET p_emp_id = LAST_INSERT_ID();
END$$
DELIMITER ;

差异总结

Oracle 需手动创建序列,而 PostgreSQL/MySQL 支持自动生成自增 ID。
MySQL 的存储过程语法更简单,但功能较弱(如不支持原生调试器)。

四、执行计划分析(Execution Plan)

执行计划用于分析 SQL 语句的查询路径与性能瓶颈。

1. 查看方法对比

数据库
命令
输出重点
Oracle EXPLAIN PLAN FOR ...

 + SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
COST

(成本)、INDEX SCAN(索引扫描)
PostgreSQL EXPLAIN (ANALYZE, BUFFERS) ...
实际执行时间、缓存命中率
MySQL EXPLAIN FORMAT=JSON ... key

(使用索引)、rows(预估行数)

示例:分析索引使用情况

-- Oracle
EXPLAIN PLAN FORSELECT*FROM employees WHERE dept_id =10;
SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY);

-- PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) SELECT*FROM employees WHERE dept_id =10;

-- MySQL
EXPLAIN FORMAT=JSON SELECT*FROM employees WHERE dept_id =10;

优化建议

  • 若发现全表扫描(FULL TABLE SCANSeq Scan),可为dept_id字段添加索引。
  • PostgreSQL 的ANALYZE选项会实际执行 SQL 并统计时间,适合精确分析。

五、扩展功能实战

1. Oracle Data Guard(高可用灾备)

-- 主库启用归档模式
ALTER DATABASE ARCHIVELOG;
-- 配置备库同步
ALTERSYSTEMSET LOG_ARCHIVE_DEST_2='SERVICE=standby_db ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)';

作用:主库数据实时同步到备库,支持故障自动切换。

2. PostgreSQL PostGIS(地理数据处理)

-- 计算两个坐标距离
SELECT ST_Distance(
  ST_GeogFromText('POINT(116.4074 39.9042)'),
  ST_GeogFromText('POINT(121.4737 31.2304)')
) AS distance;  -- 单位:米

优势:支持复杂空间计算(如相交判断、缓冲区分析)。

3. MySQL 分区表(性能优化)

-- 按时间分区
CREATETABLE sales (
  id INT AUTO_INCREMENT,
  sale_date DATE,
  amount DECIMAL(10,2),
PRIMARY KEY (id, sale_date)
) PARTITIONBYRANGE (YEAR(sale_date)) (
PARTITION p2020 VALUES LESS THAN (2021),
PARTITION p2021 VALUES LESS THAN (2022)
);

适用场景:时间序列数据(如日志、交易记录),支持快速删除旧分区。

六、核心差异总结

维度
Oracle 优势
PostgreSQL 优势
MySQL 优势
窗口函数
支持RANGE窗口和直接过滤
功能完整,社区支持好
8.0+版本功能接近标准
递归查询 CONNECT BY

语法简洁
标准WITH RECURSIVE,兼容性高
语法同 PostgreSQL,但限制较多
存储过程
功能强大(如原生调试、复杂事务控制)
开源灵活,支持多种语言扩展
语法简单,适合轻量级应用
扩展功能
Data Guard(企业级灾备)
PostGIS(地理数据处理)
分区表(轻量级优化)

以上关于SQL高级语法与函数详解(Oracle/PostgreSQL/MySQL)的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » SQL高级语法与函数详解(Oracle/PostgreSQL/MySQL)

发表回复