You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sqlglot提取Where子句列(含嵌套SQL)报Unexpected token错误解决

问题根因

你遇到的解析报错、提取不全问题来自两个核心原因:

  • 你的SQL包含{{location}}这类模板占位符、$$包裹的动态拼接标记,不属于标准SQL语法,sqlglot默认词法规则无法识别,直接抛出Invalid expression / Unexpected token错误
  • 原有逻辑仅获取了最外层SELECT语句的Where节点,没有递归遍历多层嵌套子查询、派生表内部的Where节点,只能拿到最外层过滤条件的列

可行实现方案

步骤1:预处理特殊字符

先把SQL中sqlglot无法识别的非标准语法片段替换为合法SQL结构,不会破坏原有的列引用关系:

  • 直接删除所有$$动态拼接标记
  • 将所有{{变量名}}格式的模板占位符替换为SQL通用参数占位符?

步骤2:递归遍历所有Where节点

解析SQL生成抽象语法树(AST)后,遍历整棵树找到所有层级的Where节点,提取每个节点下引用的所有列名,自动去重。


可直接运行的代码
import re
import sqlglot
import sqlglot.expressions as exp

def extract_where_columns(sql: str, include_table_alias: bool = False) -> set:
    """
    提取SQL中所有层级Where子句引用的列名
    :param sql: 待解析的原始SQL
    :param include_table_alias: 结果是否保留表别名前缀(如dc.id),默认False仅返回列名
    """
    # 预处理非标准SQL片段
    processed_sql = sql.replace("$$", "")  # 移除动态拼接标记
    processed_sql = re.sub(r"\{\{.*?\}\}", "?", processed_sql)  # 模板占位符替换为合法参数?

    # 指定MySQL方言解析,适配IF函数等MySQL专属语法,避免方言兼容错误
    ast = sqlglot.parse_one(processed_sql, dialect="mysql")

    columns = set()
    # 遍历AST中所有Where节点,覆盖所有嵌套子查询/派生表/IN子查询的Where条件
    for where_node in ast.find_all(exp.Where):
        for col in where_node.find_all(exp.Column):
            if include_table_alias:
                col_name = col.sql(dialect="mysql")
            else:
                col_name = col.name
            columns.add(col_name)
    return columns

# 简单示例测试
test_simple_sql = """select column_3, column_4 from table_name where column_1 = 10 and column_2="test"
"""
print("简单SQL提取结果:", extract_where_columns(test_simple_sql))
# 输出: {'column_1', 'column_2'}

# 替换为你自己的长SQL即可运行
# sql_query = "你的长SQL内容"
# print("复杂SQL提取结果:", extract_where_columns(sql_query))

注意事项
  • 如果需要提取JOIN关联条件ON里的引用列,只需要在遍历节点时新增判断exp.On类型即可,逻辑完全一致
  • 提取逻辑自动覆盖所有查询层级:最外层查询、子查询、派生表、IN语句内嵌套SELECT的Where条件都会被遍历,不会漏提
  • 如果你的SQL是其他数据库方言(比如PostgreSQL、SparkSQL),把代码里的dialect="mysql"换成对应方言名即可

内容的提问来源于stack exchange,提问作者Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 18:03:16