EN

用自然语言查世界杯数据:Text-to-SQL 实战(2026)

「哪些球队控球率超 60% 却输了球」——把这句话变成 SQL 自动查出来,背后的工程怎么做

返回教程列表🌐 Read in English
进阶12 分钟

用自然语言查世界杯数据:Text-to-SQL 实战(2026)

「哪些球队控球率超 60% 却输了球」——把这句话变成 SQL 自动查出来,背后的工程怎么做

世界杯数据多到查不过来。这篇带你用 Text-to-SQL 把自然语言问题自动翻译成 SQL 查询,搭一个能用大白话问的赛事数据助手,重点讲清 Schema 设计、防止查错、以及 SQL 注入安全这几个生产必须解决的问题。

用自然语言查世界杯数据:Text-to-SQL 实战

世界杯产生的数据量惊人:每场比赛几千个触球、跑动、传球事件。想从里面捞洞察——「哪些球队控球率超 60% 却输了球」「淘汰赛阶段哪个位置进球最多」——会写 SQL 的人得敲半天,不会写的只能干瞪眼。

Text-to-SQL 就是来解决这个的:你用大白话问,AI 自动翻译成 SQL 去查库,再把结果讲给你听。这篇带你搭一个世界杯数据问答助手,并讲清生产环境真正要解决的几个问题。Text-to-SQL 的通用入门可以先看Text-to-SQL:用自然语言查询数据库,这篇聚焦体育数据场景。

核心原理:Schema 是一切

Text-to-SQL 的本质,是让 LLM 看着你的数据库表结构(schema),把自然语言翻译成 SQL。所以第一要务是把 schema 描述清楚地喂给模型——它不知道你的表长什么样,就只能瞎编列名。

python
SCHEMA = """
表 matches(比赛):
  id, home_team, away_team, home_goals, away_goals, stage(group/round16/quarter/semi/final), match_date
表 team_stats(每场球队数据):
  match_id, team, possession(控球率%), shots, shots_on_target, passes, pass_accuracy(传球成功率%)
表 players(球员):
  id, name, team, position(GK/DF/MF/FW)
表 goals(进球):
  match_id, player_id, minute, type(open_play/penalty/free_kick/own_goal)
"""

Schema 描述里把每列的含义、枚举值都标注清楚(比如 stage 有哪几个取值),模型生成的 SQL 准确率会高一大截。这是性价比最高的优化。

生成 SQL

把 schema + 用户问题拼进 prompt,让模型产出 SQL:

python
from openai import OpenAI
client = OpenAI()

def to_sql(question): prompt = f"""你是 SQL 专家。根据下面的数据库 schema,把用户问题翻译成一条 PostgreSQL 查询。 只输出 SQL,不要解释。只能用 SELECT,禁止任何写操作。

{SCHEMA}

问题:{question}""" sql = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], temperature=0, ).choices[0].message.content return sql.strip().strip('`')

「哪些球队控球率超60%却输了球」

print(to_sql("Which teams had over 60% possession but still lost the match?"))

→ SELECT ts.team, ... FROM team_stats ts JOIN matches m ... WHERE ts.possession > 60 AND (输球条件)

temperature=0 必须的——生成 SQL 不需要任何创造性,要的是确定和准确。

生产环境的三个必答题

Demo 跑通容易,上生产你必须解决这三个,否则迟早出事:

1. 安全:绝不能让它执行写操作

这是第一红线。模型生成的 SQL 直接打到数据库,万一它生成了 DELETEDROP(被恶意提问诱导,或自己抽风),后果不堪设想。多层防护:

  • 只读数据库账号:给查询用的连接配一个只有 SELECT 权限的账号。这是最硬的一道防线,权限层面就堵死。
  • SQL 校验:执行前解析 SQL,拒绝非 SELECT 语句、拒绝多语句。
  • 超时和行数限制:防止一条 SELECT 把全库扫崩。
  • python
    import sqlparse

    def is_safe_select(sql): parsed = sqlparse.parse(sql) if len(parsed) != 1: # 拒绝多语句 return False stmt = parsed[0] if stmt.get_type() != 'SELECT': # 只允许 SELECT return False forbidden = ['insert', 'update', 'delete', 'drop', 'alter', 'truncate', 'grant'] return not any(w in sql.lower() for w in forbidden)

    安全这块不是可选项。底层数据用 PostgreSQL 存的话,账号权限怎么配可以参考PostgreSQL for AI Applications

    2. 准确:怎么知道它没查错

    模型可能生成语法正确但逻辑错误的 SQL——比如把「控球率超 60%」理解成「低于 60%」。几个缓解手段:

  • 回显 SQL 给用户:把生成的 SQL 一并展示,让懂的人能核对。
  • 先 EXPLAIN 再执行:检查查询计划是否合理,顺便挡掉全表扫描。
  • 给 few-shot 示例:在 prompt 里放几个「问题→正确 SQL」的范例,模型照着学,准确率明显提升。
  • 3. 结果要讲人话

    查出来一堆行,得让 LLM 把结果总结成自然语言回答。把 SQL 结果喂回模型:「根据查询结果,有 3 支球队控球占优却输球,分别是……」。这一步让整个体验从「数据库工具」变成「能对话的助手」。

    进阶:接进 Agent

    更强的玩法是把 Text-to-SQL 包成一个工具,交给 Agent,让它能多步推理:先查一个数据、根据结果再决定查什么。这种「数据分析 Agent」的搭法见用 AI 智能体构建数据分析代理

    和第一批的实时解说 Agent 对比:那个用工具调用查实时比分,这个用 Text-to-SQL 查历史数据库,是 Agent 工具能力的两个不同方向。Agent 工具调用的基础见用 LLM Agent 做实时赛事解说

    小结

    Text-to-SQL 让不懂 SQL 的人也能查复杂数据,世界杯这种数据密集场景特别合适。但记住:Schema 描述决定准确率,只读权限决定安全。这两条做扎实,剩下的都是体验优化。

    想看 AI 在世界杯的更多应用,看AI 与 2026 世界杯应用盘点

    相关工具

    OpenAIPostgreSQLsqlparseGPT-4o
    所属主题:AI 与世界杯