Apache Spark SQL 语法全景指南:从 DDL/DML 到数据检索、SQL 脚本与辅助语句
2026/9/20 13:35:25 网站建设 项目流程

Apache Spark SQL 语法全景指南:从 DDL/DML 到数据检索、SQL 脚本与辅助语句

【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark

Apache Spark SQL 是 Spark 生态中处理结构化数据的核心模块,而 SQL 语法是其对外提供的最直接、最广泛使用的接口。本文以 Spark 官方文档中 SQL Syntax 总览 为主体骨架,系统梳理 Spark SQL 支持的五类语句——DDL(数据定义)、DML(数据操作)、数据检索(SELECT 与 EXPLAIN)、SQL 脚本(过程化逻辑)以及辅助语句,并结合仓库中的 ANTLR 语法文件与解析器源码,讲清每类语句的定位、语法要点与底层解析机制。读完本文,你将能快速定位任意一条 Spark SQL 语句的完整语法定义,理解 Spark 如何将一条 SQL 文本逐步解析为可执行的逻辑计划与物理计划,并据此编写规范、可高效执行的查询。

一、从 SQL 语法文档到执行计划:Spark 的解析链路

在深入各类语句之前,先理解 Spark 如何处理一条 SQL。整个 SQL 语法体系由两大部分承载:

  • 语法定义:仓库中 SqlBaseParser.g4 与 SqlBaseLexer.g4 是 ANTLR 4 文法文件(其声明"adapted from Presto's SqlBase.g4 grammar"),定义了从顶层compoundOrSingleStatement到每个具体语句的完整语法规则。
  • 解析实现:SparkSqlParser.scala 继承AbstractSqlParser,通过parsePlanWithParameters调用语法文件的compoundOrSingleStatement()入口,将解析树交给SparkSqlAstBuilder转换为 Catalyst 的逻辑计划(LogicalPlan),若结果是CompoundPlanStatement(SQL 脚本复合体)则原样返回。

从语法文件可以看到解析器内置了若干可配置的行为开关,它们直接影响语句的解析语义:

语法文件成员开关含义关联配置
SQL_standard_keyword_behavior为 true 时关键字遵循 ANSI SQL 标准spark.sql.parser.ansi.enabled(配合 ANSI 模式)
double_quoted_identifiers为 true 时双引号内容按标识符而非字符串解析spark.sql.parser.escapedStringLiterals相关 ANSI 设置
legacy_setops_precedence_enabled控制 INTERSECT 与 UNION/EXCEPT 的优先级(false 时遵循 SQL 标准)spark.sql.legacy.setopsPrecedence.enabled
legacy_identifier_clause_only控制IDENTIFIER('literal')的解析方式spark.sql.legacy.identifierClause
single_character_pipe_operator_enabled是否允许单字符|作为 SQL 管道运算符管道语法开关

顶层语法规则compoundOrSingleStatementsingleStatementsingleCompoundStatement组成,后者即BEGIN (NOT ATOMIC)? compoundBody? END形式的 SQL 脚本复合语句。而singleStatement内部又分为dmlStatementusesetCatalogcreateTableanalyzeshowTablesexplaincacheTableloadData等数十条具体规则——这正是文档中五类语句在语法层面的映射。理解了这条"文本 → 词法 → 语法树 → 逻辑计划 → 物理计划"的链路,后续阅读各类语句时就能知其然也知其所以然。

二、DDL 语句:定义与修改数据库对象结构

Data Definition Statements 用于创建或修改数据库中数据库对象的结构。Spark SQL 支持以下 DDL 语句:

语句文档位置用途
ALTER DATABASEsql-ref-syntax-ddl-alter-database.md修改数据库属性、位置
ALTER TABLEsql-ref-syntax-ddl-alter-table.md修改表结构(增删列、改分区、改属性等)
ALTER VIEWsql-ref-syntax-ddl-alter-view.md修改视图定义
COMMENT ONsql-ref-syntax-ddl-comment.md为表/列添加注释
CREATE DATABASEsql-ref-syntax-ddl-create-database.md创建数据库
CREATE FUNCTION (External)sql-ref-syntax-ddl-create-function.md注册外部(Hive UDF/UDTF/UDAF)函数
CREATE FUNCTION (SQL)sql-ref-syntax-ddl-create-sql-function.md创建 SQL 标量/表值函数
CREATE TABLEsql-ref-syntax-ddl-create-table.md定义表(入口页,含三种子形态)
CREATE VIEWsql-ref-syntax-ddl-create-view.md创建视图
DECLARE VARIABLEsql-ref-syntax-ddl-declare-variable.md声明会话级变量
DROP DATABASEsql-ref-syntax-ddl-drop-database.md删除数据库
DROP FUNCTIONsql-ref-syntax-ddl-drop-function.md删除函数
DROP TABLEsql-ref-syntax-ddl-drop-table.md删除表
DROP TEMPORARY VARIABLEsql-ref-syntax-ddl-drop-variable.md删除临时变量
DROP VIEWsql-ref-syntax-ddl-drop-view.md删除视图
REPAIR TABLEsql-ref-syntax-ddl-repair-table.md恢复/刷新表分区元数据
TRUNCATE TABLEsql-ref-syntax-ddl-truncate-table.md清空表数据
USE DATABASEsql-ref-syntax-ddl-usedb.md切换当前数据库

2.1 CREATE TABLE:三种建表形态

CREATE TABLE的入口文档将其划分为三种形态:

  • CREATE TABLE USING DATA_SOURCE:使用 DataSource 数据源(如USING PARQUETUSING CSV)建表,可配合PARTITIONED BYLOCATIONTBLPROPERTIESOPTIONS等子句。
  • CREATE TABLE USING HIVE FORMAT:使用 Hive SerDe 格式建表(STORED ASROW FORMAT等)。
  • CREATE TABLE LIKE:以一张已有表为模板创建同构新表。

语法层面,SqlBaseParser.g4 中的createTableHeader (LEFT_PAREN tableElementList RIGHT_PAREN)? tableProvider? createTableClauses (AS? query)?规则完整刻画了建表语法,其中AS? queryCREATE TABLE ... AS SELECT(CTAS)能力。与CREATE TABLE并列的还有replaceTableHeader对应的CREATE OR REPLACE TABLE

2.2 变量声明:DECLARE / DROP TEMPORARY VARIABLE

值得关注的是DECLARE VARIABLEDROP TEMPORARY VARIABLE两条语句,它们服务于 Spark 3.4+ 引入的 SQL 变量体系(配合参数化查询与 SQL 脚本)。语法文件中的declareVariable规则支持带DEFAULT值的变量声明。变量可进一步与文档中的 SET VAR、EXECUTE IMMEDIATE 配套使用,构成会话内可编程的数据处理环境。

三、DML 语句:增、改、删数据

Data Manipulation Statements 用于添加、变更或删除数据。Spark SQL 支持以下 DML 语句:

语句文档位置用途
INSERT TABLEsql-ref-syntax-dml-insert-table.md向表插入或覆盖数据
INSERT OVERWRITE DIRECTORYsql-ref-syntax-dml-insert-overwrite-directory.md将查询结果写入外部目录
MERGE INTOsql-ref-syntax-dml-merge-into.md依据源数据对目标表执行插入/更新/删除
LOADsql-ref-syntax-dml-load.md从文件路径加载数据到 Hive 表

3.1 INSERT 的完整语法形态

INSERT语句插入新行或覆盖表中已有数据,插入行可由值表达式指定,也可由查询结果产生。其语法如下:

INSERT [ WITH SCHEMA EVOLUTION ] [ INTO | OVERWRITE ] [ TABLE ] table_identifier [ partition_spec ] [ ( column_list ) | [BY NAME] ] { VALUES ( { value | NULL } [ , ... ] ) [ , ( ... ) ] | query } INSERT [ WITH SCHEMA EVOLUTION ] INTO [ TABLE ] table_identifier [ BY NAME ] REPLACE WHERE boolean_expression query

关键参数解析:

  • WITH SCHEMA EVOLUTION:允许本次 INSERT 依据源查询自动演进目标表 schema(新增列、拓宽数据类型),具体能力取决于底层 connector。
  • partition_specPARTITION ( partition_col_name = partition_col_val [ , ... ] ),支持类型化字面量(如date'2019-01-02')。
  • column_list:按列名将源查询列重排以匹配表 schema,需注意所有列必须真实存在且不重复,列数须与 VALUES/查询输出严格一致。
  • BY NAME:默认按位置匹配列与嵌套字段;BY NAME改为按名称匹配,允许源与目标列顺序不同。
  • query:可来源于 SELECT、Inline Table 或FROM语句。

语法文件中对应的INSERT (OVERWRITE | INTO)? ...规则将INSERT INTOINSERT OVERWRITEINSERT OVERWRITE DIRECTORY(含LOCALSTORED AS等变体)统一收纳。仓库中的使用示例与测试大量覆盖了INSERT INTO ... VALUESINSERT OVERWRITE TABLEINSERT OVERWRITE DIRECTORY三种形态,例如在分区表students中插入单行:

CREATE TABLE students (name VARCHAR(64), address VARCHAR(64)) USING PARQUET PARTITIONED BY (student_id INT); INSERT INTO students VALUES ('Amy Smith', '123 Park Ave, San Jose', 111111);

3.2 MERGE INTO 与 LOAD

  • MERGE INTO:以源表(可通过USING子句指定,含AS OF时态表)驱动,对目标表执行WHEN MATCHED(UPDATE/DELETE)与WHEN NOT MATCHED(INSERT)分支操作,是湖仓场景 upsert 的标准手段。
  • LOAD:将本地或远程文件系统中的数据加载进 Hive 表,支持LOAD DATA [LOCAL] INPATH ... INTO TABLE语法。

四、数据检索语句:SELECT 及其子句体系

Spark 支持符合 ANSI SQL 标准的SELECT语句,用于从一个或多个表中检索结果集。SELECT及其关联语句是 Spark SQL 使用频率最高、语法最丰富的部分,完整定义见 SELECT。

4.1 SELECT 整体语法

[ WITH with_query [ , ... ] ] select_statement [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select_statement, ... ] [ ORDER BY { expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [ , ... ] } ] [ SORT BY { expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [ , ... ] } ] [ CLUSTER BY { expression [ , ... ] } ] [ DISTRIBUTE BY { expression [, ... ] } ] [ WINDOW { named_window [ , WINDOW named_window, ... ] } ] [ LIMIT { ALL | expression } ]

其中select_statement定义为:

SELECT [ hints , ... ] [ ALL | DISTINCT ] { [ [ named_expression | regex_column_names | star ] [ , ... ] | TRANSFORM (...) ] } FROM { from_item [ , ... ] } [ PIVOT clause ] [ UNPIVOT clause ] [ LATERAL VIEW clause ] [ ... ] [ WHERE boolean_expression ] [ GROUP BY expression [ , ... ] ] [ HAVING boolean_expression ] [ WINDOW clause ] [ QUALIFY boolean_expression ]

4.2 核心子句速查

语法元素语义要点
with_query在主查询前声明 CTE,便于抽象复用子查询块
hints指导优化器做连接策略选择与数据重分区
ALL/DISTINCT是否对结果去重,ALL为默认
named_expression带别名的表达式,语法为expression [[AS] alias]
star*选择 FROM 子句中一个或所有关系的列
from_item输入来源:表、JOIN、ASOF JOIN、PIVOT、UNPIVOT、表值函数、JSON_TABLE、内联表、UNNEST、子查询(可 LATERAL)、File
WHERE基于布尔表达式过滤 FROM 结果
GROUP BY配合聚合函数(MIN/MAX/COUNT/SUM/AVG 等)分组聚合;聚合函数后可挂FILTER子句只对匹配行聚合
HAVING对 GROUP BY 产出行过滤;无 GROUP BY 时表示全局聚合
QUALIFY在窗口函数求值后过滤行;SELECT 列表或 QUALIFY 条件中必须至少含一个窗口函数,QUALIFY 内不允许聚合函数
ORDER BY/SORT BY前者对整个结果集全局排序,后者仅在每个分区内排序;两者互斥
CLUSTER BY/DISTRIBUTE BY前者等价于 DISTRIBUTE BY + SORT BY(重分区并排序),后者仅重分区;与 ORDER BY 互斥
LIMIT限制返回的最大行数,常与 ORDER BY 搭配产生确定性结果

4.3 CTE:公共表表达式

CTE 定义一个临时结果集,可在单条 SQL 语句作用域内被多次引用,语法为:

WITH common_table_expression [ , ... ]

其中common_table_expression定义为:

expression_name [ ( column_name [ , ... ] ) ] [ AS ] [ [ NOT ] MATERIALIZED ] ( query )

MATERIALIZED/NOT MATERIALIZED允许用户显式提示优化器是否物化 CTE 结果,这在重复引用同一子查询时可显著影响执行效率。

4.4 窗口函数

窗口函数基于一组行(窗口)计算每行的返回值,适用于移动平均、累计统计、相对位置取值等场景。其语法为:

window_function [ nulls_option ] OVER ( [ { PARTITION | DISTRIBUTE } BY partition_col_name = partition_col_val ( [ , ... ] ) ] { ORDER | SORT } BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [ , ... ] [ window_frame ] )
  • 窗口函数类型:排名类(RANK | DENSE_RANK | PERCENT_RANK | NTILE | ROW_NUMBER)、分析类(CUME_DIST | LAG | LEAD | NTH_VALUE | FIRST_VALUE | LAST_VALUE)、聚合类(MAX | MIN | COUNT | SUM | AVG | ...)。
  • nulls_option{ IGNORE | RESPECT } NULLS,默认RESPECT NULLS;仅LAG/LEAD/NTH_VALUE/FIRST_VALUE/LAST_VALUE支持IGNORE NULLS
  • window_frame{ RANGE | ROWS } { frame_start | BETWEEN frame_start AND frame_end },帧端点可为UNBOUNDED PRECEDING | offset PRECEDING | CURRENT ROW | offset FOLLOWING | UNBOUNDED FOLLOWING,省略frame_end时默认为CURRENT ROW

4.5 检索语法的完整清单

SELECT 主文档 及其子页面覆盖了以下全部子句与构造:

  • Common Table Expression
  • CLUSTER BY Clause、DISTRIBUTE BY Clause
  • GROUP BY Clause、HAVING Clause
  • Hints
  • Inline Table、UNNEST Clause、File
  • JOIN、ASOF JOIN
  • LIKE Predicate
  • LIMIT Clause、OFFSET Clause
  • ORDER BY Clause、SORT BY Clause
  • Set Operators
  • TABLESAMPLE
  • Table-valued Function
  • JSON_QUERY、JSON_ARRAY、JSON_TABLE、JSON_VALUE、JSON_EXISTS
  • WHERE Clause
  • Aggregate Function、Window Function
  • CASE Clause
  • PIVOT Clause、UNPIVOT Clause
  • LATERAL VIEW Clause、LATERAL SUBQUERY
  • TRANSFORM Clause
  • star (*) Clause

其中regex_column_names是 Spark 较有特色的能力:当spark.sql.parser.quotedRegexColumnNames为 true 时,SELECT 中用反引号包裹的标识符会被解释为正则表达式。例如下面这条语句只会取到列c

SELECT `(a|b)?+.+` FROM ( SELECT 1 as a, 2 as b, 3 as c )

TRANSFORM子句则提供 Hive 风格的 transform 查询:通过 fork 并运行用户指定的命令或脚本对输入做变换。

4.6 EXPLAIN:观察查询计划

Spark 提供EXPLAIN语句为给定语句生成逻辑/物理计划。默认仅输出物理计划,语法为:

EXPLAIN [ EXTENDED | CODEGEN | COST | FORMATTED ] statement
  • EXTENDED:依次生成 Parsed Logical Plan(未解析逻辑计划)、Analyzed Logical Plan(已解析并类型化)、Optimized Logical Plan(经优化规则集转换)与 Physical Plan。
  • CODEGEN:生成语句对应的代码(如有)及物理计划。
  • FORMATTED:输出物理计划大纲与节点详情两个部分。
  • COST:当计划节点统计信息可用时,输出逻辑计划与统计信息。

典型输出(默认模式):

EXPLAIN select k, sum(v) from values (1, 2), (1, 3) t(k, v) group by k; +----------------------------------------------------+ | plan| +----------------------------------------------------+ | == Physical Plan == *(2) HashAggregate(keys=[k#33], functions=[sum(cast(v#34 as bigint))]) +- Exchange hashpartitioning(k#33, 200), true, [id=#59] +- *(1) HashAggregate(keys=[k#33], functions=[partial_sum(cast(v#34 as bigint))]) +- *(1) LocalTableScan [k#33, v#34] +----------------------------------------------------+

可以看到sum被拆分为部分聚合(partial_sum)与最终聚合两段,Exchange hashpartitioning承担了跨节点 Shuffle 职责——这正是分布式聚合在物理计划层面的体现。

五、SQL 脚本语句:过程化逻辑

Spark SQL 提供 SQL 脚本(SQL scripting)能力,用于在 SQL 中执行过程化逻辑。语法层面,SqlBaseParser.g4 的singleCompoundStatement规则定义了BEGIN (NOT ATOMIC)? compoundBody? END的复合语句结构,compoundStatement则覆盖了变量赋值、IF/WHILE/REPEAT/LOOP/FOR 循环、CASE、LEAVE/ITERATE 跳转、DECLARE 等过程化构造,对应文档位于 control-flow 目录:

  • CASE:多分支条件选择
  • compound statement:BEGIN...END 复合语句块
  • FOR:按查询结果或计数器循环
  • IF:条件分支
  • ITERATE:跳回循环开头继续迭代
  • LEAVE:跳出循环或语句块
  • LOOP:无条件循环
  • REPEAT:先执行后判断的循环
  • WHILE:先判断后执行的循环

SQL 脚本可与DECLARE VARIABLESET VAREXECUTE IMMEDIATE组合,在单个脚本内完成"声明变量 → 循环遍历 → 动态执行"的完整业务流程,适合在spark-sqlCLI、JDBC/ODBC 或 Spark Connect 客户端中直接提交多语句脚本。

六、辅助语句(Auxiliary Statements)

辅助语句覆盖资源管理、缓存、元数据查看、会话配置管理、表统计与刷新等运维与调试能力,共 30 条:

资源管理类

  • ADD FILE、ADD JAR:向执行器分发文件/依赖
  • LIST FILE、LIST JAR:列出已分发资源

缓存类

  • CACHE TABLE:将表或查询结果缓存进内存(支持LAZYOPTIONS
  • UNCACHE TABLE、CLEAR CACHE:清除缓存
  • REFRESH TABLE、REFRESH、REFRESH FUNCTION:刷新缓存/函数元数据

元数据查看类(SHOW / DESCRIBE 系列)

  • DESCRIBE DATABASE、DESCRIBE FUNCTION、DESCRIBE QUERY、DESCRIBE TABLE
  • SHOW COLLATIONS、SHOW COLUMNS、SHOW CREATE TABLE、SHOW DATABASES、SHOW FUNCTIONS、SHOW PARTITIONS、SHOW TABLE EXTENDED、SHOW TABLES、SHOW TBLPROPERTIES、SHOW VIEWS

配置与会话管理类

  • SET、RESET:查看/设置/重置 Spark 配置
  • SET PATH:管理 SQL 中未限定名称的解析搜索路径
  • SET VAR:给会话变量赋值

统计与动态执行类

  • ANALYZE TABLE:收集表/列统计信息(COMPUTE STATISTICS,可指定列)
  • EXECUTE IMMEDIATE:动态执行一条 SQL(支持USING参数绑定)

语法文件中这些语句均有对应规则,例如ANALYZE TABLE identifierReference partitionSpec? COMPUTE STATISTICS (simpleIdentifier | FOR COLUMNS identifierSeq | FOR ALL COLUMNS)?SHOW TABLES ((FROM | IN) identifierReference)? (LIKE? pattern=stringLit)? (AS JSON)?CACHE LAZY? TABLE ...UNCACHE TABLE (IF EXISTS)? ...CLEAR CACHE等,展示了辅助语句在解析层如何被精确识别。

七、使用建议与延伸阅读

Spark SQL 的语法体系庞大但组织清晰:DDL 管结构、DML 管数据、SELECT 管检索、SQL 脚本管过程逻辑、辅助语句管运维与调试。实际使用时建议:

  1. 先定位再细读:不确定某条语句的写法时,先按本文的五大分类找到对应子文档(均在 docs 目录下),再阅读其中的完整语法、参数表与示例。
  2. 善用 EXPLAIN 调优:对任何复杂查询,先用EXPLAIN EXTENDED观察 Parsed → Analyzed → Optimized → Physical 四层计划,确认过滤条件下推、连接策略、Shuffle 分布是否符合预期。
  3. 关注语句间的组合:CTE + 窗口函数 +QUALIFYMERGE INTO+ 分区裁剪、CACHE TABLE+REFRESH、变量声明 + SQL 脚本循环,这些组合能覆盖绝大多数数仓与数据湖上的典型场景。
  4. 验证运行环境前提:部分能力(如WITH SCHEMA EVOLUTION、JSON 系列函数、SQL 脚本)与数据源 connector 能力及 Spark 版本相关,请以当前仓库 pom.xml 对应的版本行为为准。

继续深入可阅读 SQL Reference 总入口,其中按语法、数据类型、函数、错误条件等维度展开;若想了解语法背后的解析与优化实现,则可从 SqlBaseParser.g4 与 SparkSqlParser.scala 入手,对照本文第一节梳理的解析链路逐条追踪。

【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询