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

Python实现列表内SQL表达式字符串子串级对比的问题求解

问题原因
  • 现有实现直接使用, 作为分隔符切割字符串,没有考虑concat()、case when这类SQL表达式内部本身就包含逗号的场景,会把完整的单个选择项拆成多个无效片段,后续集合计算自然不符合预期。
  • 现有实现只计算了后一个字符串比前一个多的项,没有按照预期合并两个字符串的所有去重后的完整选择项。
解决实现

通过状态机逻辑实现正确的SQL选择项拆分,拆分时忽略括号、特殊语句块内部的逗号,再进行去重合并即可:

def split_sql_select_items(s):
    items = []
    current = []
    # 状态标记:括号嵌套层数、是否在case语句块中
    bracket_level = 0
    in_case = 0
    for char in s:
        if char == '(':
            bracket_level += 1
        elif char == ')':
            bracket_level -= 1
        elif ''.join(current[-3:]).lower() == 'case' and bracket_level == 0:
            in_case = 1
        elif ''.join(current[-2:]).lower() == 'end' and bracket_level == 0 and in_case:
            in_case = 0
        # 只有不在括号、case块内的逗号才是分割符
        elif char == ',' and bracket_level == 0 and in_case == 0:
            items.append(''.join(current).strip())
            current = []
            continue
        current.append(char)
    # 加入最后一个项
    if current:
        items.append(''.join(current).strip())
    return items

lis = [
'concat(tb1.col1, tb1.col2, tb1.col3) as alias1, tb1.col4, case when tb2.col2>1 then 1 else 0 end as alias3', 
'concat(tb1.col1, tb1.col2, tb1.col3) as alias1, concat(tb2.col1, tb2.col2, tb2.col3) as alias2, case when tb1.col1>1 then 1 else 0 end as alias4, tb3.col1'
]

# 拆分所有项再去重,保留首次出现的顺序
seen = set()
result = []
for s in lis:
    items = split_sql_select_items(s)
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)

print(result)
运行输出
['concat(tb1.col1, tb1.col2, tb1.col3) as alias1', 'tb1.col4', 'case when tb2.col2>1 then 1 else 0 end as alias3', 'concat(tb2.col1, tb2.col2, tb2.col3) as alias2', 'case when tb1.col1>1 then 1 else 0 end as alias4', 'tb3.col1']

和预期输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 01:54:05