【问题标题】:How to get table names from join condition using gsqlarser?如何使用 gsqlarser 从连接条件中获取表名?
【发布时间】:2020-12-21 15:46:24
【问题描述】:

我正在尝试实现 sqlparser 并使用来自here 的 gsqlparser。 jar 的来源是 Java,但我在 Scala 中实现相同。

下面是我的查询,其中包含一个连接条件。

 SELECT e.last_name AS name, e.commission_pct comm, e.salary * 12 "Annual Salary" FROM scott.employees AS e right join scott.companies as c on c.orgid = e.orgid and c.orgname = e.orgn WHERE e.salary > 1000 ORDER BY e.first_name, e.last_name

我能够解析查询以读取列的名称和别名、条件、表名(直接在查询中检查表名),如下所示。

val sqlParser = new TGSqlParser(EDbVendor.dbvsnowflake)
sqlParser.sqltext = "SELECT e.last_name AS name, e.commission_pct comm, e.salary * 12 \"Annual Salary\" FROM scott.employees AS e right join scott.companies as c on c.orgid = e.orgid and c.orgname = e.orgn WHERE e.salary > 1000 ORDER BY e.first_name, e.last_name"
val selectStmnt = sqlParser.sqltext
    println("Columns List:")
for(i <- 0 until selectStmnt.getResultColumnList.size()) {
  val resCol = selectStmnt.getResultColumnList.getResultColumn(i)
  println("Column: " + resCol.getExpr.toString + " Alias: " + resCol

.getAliasClause().toString)
    }

输出:

Columns List:
Column: e.last_name Alias: name
Column: e.commission_pct Alias: comm
Column: e.salary * 12 Alias: "Annual Salary"

我正在尝试解析连接条件并获取其中的详细信息

for(j <- 0 until selectStmnt.getJoins.size()) {
    println(selectStmnt.getJoins.getJoin(j).getTable)
}

这里的问题是查询中只有一个连接条件,所以返回的大小是1。 因此输出为scott.employees。 如果我使用getJoinItems

println("Parsing Join items")
for(j <- 0 until selectStmnt.getJoins.size()) {
    println(selectStmnt.getJoins.getJoin(j).getJoinItems)
}

我通过从连接条件中截断第一个表来获得输出,如下所示:

scott.companies as c on c.orgid = e.orgid and c.orgname = e.orgn

方法:getJoinItems() 返回一个列表:TJoinItemList,我想遍历它。但即使它的大小也是 1。

println(selectStmnt.getJoins.getJoin(j).getJoinItems.size()) -> 1

我现在没有主意了。谁能告诉我如何解析查询的连接条件并获取连接中的表名?

【问题讨论】:

    标签: java scala sql-parser general-sql-parser


    【解决方案1】:

    我无法访问 GSP 中的 Snowflake 方言,但我使用以下查询使用 Teradata 方言模拟了这种场景并创建了一个 sql 解析器。

    SELECT e.last_name as name
    FROM department d
    RIGHT JOIN 
    trimmed_employee e
    ON d.dept_id = e.emp_id
    WHERE e.salary > 1000
    ORDER BY e.first_name
    
    

    这是获取departmenttrimmed_employee 两个表的 Groovy 代码。它归结为迭代每个连接,同时使用curJoin.joinItems 收集当前连接的项目(joinItems),前提是它不为空。

    stmt.joins.asList().collect { curJoin -> 
      [curJoin.table] + (curJoin?.joinItems?.asList()?.collect { joinItems ->  joinItems.table } ?: [])
    }.flatten()
    

    结果:

    department
    trimmed_employee
    

    对于你在我的例子中提到的这个简单的 sql,下面的代码也可以。

    stmt.tables.asList()
    

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 2014-01-02
      • 2021-04-02
      • 2020-07-25
      • 2018-04-02
      • 2019-11-19
      相关资源
      最近更新 更多