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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:27:39