Pipe语法(|>)
功能描述
Pipe语法(管道操作符 |>)是Spark 4.0的SQL语法扩展,允许以管道(pipeline)方式组织SQL查询。Pipe语法将查询从嵌套的函数调用风格改为从上到下的线性流程,使复杂查询更易读写。
Pipe语法与现有SQL语法完全兼容,可以在任何查询中混合使用。
语法格式
FROM table_source |> WHERE condition |> SELECT select_expr [, ...] |> ORDER BY col_name [ASC|DESC] [, ...] |> LIMIT num_rows
参数说明
| 操作符 | 语法 | 说明 |
|---|---|---|
| FROM / TABLE | FROM 或 TABLE | 从源表开始,返回所有行 |
| SELECT | |> SELECT [[AS] alias], ... | 计算表达式,生成新列(不支持聚合函数,聚合用 AGGREGATE) |
| EXTEND | |> EXTEND [[AS] alias], ... | 在输入表基础上追加新列 |
| SET | |> SET = , ... | 替换已有列的值 |
| DROP | |> DROP , ... | 删除指定列 |
| AS | |> AS | 为输入表引入新别名 |
| WHERE | |> WHERE | 过滤行(无需单独的 HAVING 或 QUALIFY) |
| LIMIT | |> [LIMIT ] [OFFSET ] | 限制返回行数和跳过行数 |
| AGGREGATE | |> AGGREGATE <agg_expr> GROUP BY <group_expr> | 聚合操作(全表或分组) |
| JOIN | |> [LEFT|RIGHT|FULL|CROSS|SEMI|ANTI] JOIN ON | 连接操作 |
| ORDER BY | |> ORDER BY [ASC|DESC], ... | 排序 |
| UNION ALL | |> UNION ALL | 合并结果集 |
| TABLESAMPLE | |> TABLESAMPLE ( {ROWS|PERCENT}) | 采样 |
| PIVOT | |> PIVOT (agg_expr FOR col IN (val1, ...)) | 行转列 |
| UNPIVOT | |> UNPIVOT (value_col FOR key_col IN (col1, ...)) | 列转行 |
注意事项
- Pipe语法以FROM子句开头。
- 每个 |> 操作符处理前一步的输出,形成管道链。
- WHERE 操作符可用于任何位置,无需单独的 HAVING 或 QUALIFY。
- Pipe语法不改变查询的语义,只是提供了不同的书写方式。
- EXTEND/JOIN操作符在简单内联查询上可能触发 toAttribute on unresolved object 内部错误,建议使用 SELECT * FROM (subquery) AS alias \|> ... 的子表别名方式。
- |> SET 操作符仅支持单段式键(如 key_name),不支持多段式配置键(如 spark.sql.ansi.enabled)。
示例1:基本管道查询
FROM employees |> WHERE department = 'Engineering' |> SELECT name, salary |> ORDER BY salary DESC |> LIMIT 10;
等价于:
SELECT name, salary FROM employees WHERE department = 'Engineering' ORDER BY salary DESC LIMIT 10;
示例2:使用EXTEND添加计算列
VALUES (0), (1) tab(col) |> EXTEND col * 2 AS result;
结果:
| col | result |
|---|---|
| 0 | 0 |
| 1 | 2 |
示例3:使用SET修改列值
VALUES (0), (1) tab(col) |> SET col = col * 2;
结果:
| col |
|---|
| 0 |
| 2 |
示例4:使用AGGREGATE分组聚合
-- 全表聚合 VALUES (0), (1) tab(col) |> AGGREGATE COUNT(col) AS count; -- 分组聚合 VALUES (0, 1), (0, 2) tab(col1, col2) |> AGGREGATE COUNT(col2) AS count GROUP BY col1;
示例5:使用JOIN
SELECT 0 AS a, 1 AS b |> AS lhs |> JOIN VALUES (0, 2) rhs(a, b) ON (lhs.a = rhs.a);
示例6:复杂管道(TPC-H Q13改写)
标准SQL:
SELECT c_count, COUNT(*) AS custdist
FROM
(SELECT c_custkey, COUNT(o_orderkey) c_count
FROM customer
LEFT OUTER JOIN orders ON c_custkey = o_custkey
AND o_comment NOT LIKE '%unusual%packages%' GROUP BY c_custkey
) AS c_orders
GROUP BY c_count
ORDER BY custdist DESC, c_count DESC; 管道语法:
FROM customer |> LEFT OUTER JOIN orders ON c_custkey = o_custkey AND o_comment NOT LIKE '%unusual%packages%' |> AGGREGATE COUNT(o_orderkey) c_count GROUP BY c_custkey |> AGGREGATE COUNT(*) AS custdist GROUP BY c_count |> ORDER BY custdist DESC, c_count DESC;
核心特性
独立性与互操作性
- 每个管道操作符接收一个输入表,独立地对行进行操作。
- 对于任何N个管道操作符的有效链,前M个(M ≤ N)操作符也构成有效查询。
- 可以在任何有效的标准SQL查询后面追加管道操作符。
- 表子查询可以使用标准SQL语法或管道语法编写。
- 视图、DDL、DML语句中都可以包含管道语法查询。
投影操作
- SELECT:计算新表达式,生成新表。
- EXTEND:在保留原列的基础上追加新列。
- SET:替换已有列的值。
- DROP:删除指定列。
聚合操作
- AGGREGATE 合并了 GROUP BY + SELECT 的功能,无需重复表达式。
- 分组表达式支持直接在 GROUP BY 中指定别名。
- 输出列自动包含分组列和聚合列。