如何用Python提取SQL查询条件中的列名与对应值
用Python提取SQL查询中条件涉及的列名与对应值
需求说明
需要从SQL查询语句中提取所有条件涉及的列名及其对应值,包括CASE WHEN中的判断条件和WHERE子句(含嵌套子查询)里的条件。
示例SQL
SELECT CASE WHEN grade=90 THEN "A1" WHEN grade=80 THEN "B1" WHEN grade=70 THEN "C1" ELSE "D1" END as GradeRank, * FROM employees WHERE age > 30 AND department = 'sales' AND salary IN (SELECT salary FROM employees WHERE name like "Adam%")
期望输出
output: [("age", 30), ("department", "sales"), ("name", "Adam%"), ("grade", 90), ("grade", 80), ("grade", 70)]
当前问题
使用正则表达式仅能拆分出条件语句片段,无法精准提取列名和对应值,实际输出如下:
['age > 30', 'AND', "department = 'sales'", 'AND', "salary in (SELECT salary from employees WHERE name like 'Adam%')"]
解决方案
正则表达式难以处理SQL复杂的语法结构(如嵌套子查询、CASE WHEN、多种比较运算符),推荐使用专业的SQL解析库sqlglot,它能将SQL转换为抽象语法树(AST),方便遍历提取目标信息。
步骤1:安装sqlglot
pip install sqlglot
步骤2:编写提取代码
import sqlglot from sqlglot import exp def extract_condition_columns(sql): result = [] # 解析SQL为抽象语法树 parsed = sqlglot.parse_one(sql) # 提取CASE WHEN中的WHEN条件 for case in parsed.find_all(exp.Case): for when in case.args.get("expressions", []): if isinstance(when, exp.When): condition = when.args.get("condition") if isinstance(condition, exp.EQ): col_name = condition.args.get("this").name value = condition.args.get("expression").args.get("this") result.append((col_name, value)) # 提取WHERE子句(含子查询)中的条件 def traverse_condition_node(node): # 处理AND/OR连接的多条件 if isinstance(node, (exp.And, exp.Or)): traverse_condition_node(node.args.get("this")) traverse_condition_node(node.args.get("expression")) return # 处理比较类条件:>、=、LIKE等 if isinstance(node, (exp.GT, exp.EQ, exp.Like)): col_name = node.args.get("this").name value_node = node.args.get("expression") # 处理IN子查询中的嵌套WHERE条件 if isinstance(value_node, exp.Subquery): sub_where = value_node.args.get("expression").find(exp.Where) if sub_where: traverse_condition_node(sub_where.args.get("expression")) else: # 提取字面量值(字符串、数字等) if isinstance(value_node, exp.Literal): result.append((col_name, value_node.value)) where_clause = parsed.find(exp.Where) if where_clause: traverse_condition_node(where_clause.args.get("expression")) return result # 测试示例SQL sample_sql = """ SELECT CASE WHEN grade=90 THEN "A1" WHEN grade=80 THEN "B1" WHEN grade=70 THEN "C1" ELSE "D1" END as GradeRank, * FROM employees WHERE age > 30 AND department = 'sales' AND salary IN (SELECT salary FROM employees WHERE name like "Adam%") """ print("output:", extract_condition_columns(sample_sql))
代码说明
- 该代码会遍历SQL的AST结构,分别提取
CASE WHEN中的判断条件和WHERE子句(包括嵌套子查询内的WHERE)中的列名与对应值。 - 支持处理
>、=、LIKE等常见比较运算符,以及AND/OR连接的多条件场景。
内容的提问来源于stack exchange,提问作者Gopesh Khandelwal
相关产品推荐
相关产品推荐

