一. 定义
with A as (select * from class)
也就是将重复用到的大批量 的SQL语句,放到with as 中,加一个别名,在后面用到的时候就可以直接用。对于大批量的SQL数据,起到优化的作用。
with子句的返回结果存到用户的临时表空间中,只做一次查询,反复使用
,提高效率。
二. 用法
- with子句只能被select查询块引用
- 在同级select前有多个查询定义的时候,第1个用with,后面的不用with,并且用逗号隔开。
- 最后一个with 子句与下面的查询之间不能有逗号,只通过右括号分割,with 子句的查询必须用括号括起来。
-- 针对一个别名
-- –相当于建了个e临时表
with e as (select * from scott.emp e where e.empno=7499)
select * from e;
-- –针对多个别名,相当于建了e、d临时表
with
e as (select * from scott.emp),
d as (select * from scott.dept)
select * from e, d where e.deptno = d.deptno;
三. 解析
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.9</version>
</dependency>
官网文档:
https://jsqlparser.github.io/JSqlParser/usage.html#parse-a-sql-statements
//去除 with语法下的别名
private static Set<String> removeWithAlias(String sql, Set<String> tables) {
if (sql.contains("with ")) {
PlainSelect select = null;
try {
select = (PlainSelect) CCJSqlParserUtil.parse(sql);
List<WithItem> withItemsList = select.getWithItemsList();
List<String> withAlias = withItemsList.stream()
.map(withItem -> withItem.getAlias().getName())
.collect(Collectors.toList());
return tables.stream().filter(t -> !withAlias.contains(t))
.collect(Collectors.toSet());
} catch (Exception e) {
e.printStackTrace();
}
}
return tables;
}