用自然语言查世界杯数据:Text-to-SQL 实战(2026)
「哪些球队控球率超 60% 却输了球」——把这句话变成 SQL 自动查出来,背后的工程怎么做
用自然语言查世界杯数据: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 直接打到数据库,万一它生成了 DELETE 或 DROP(被恶意提问诱导,或自己抽风),后果不堪设想。多层防护:
SELECT 把全库扫崩。python
import sqlparsedef 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%」。几个缓解手段:
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 世界杯应用盘点。
相关工具
相关教程
LLM查询重写、执行计划分析与自动索引推荐
把赛程、球队、历史战绩喂给大模型,做一个能用大白话问的赛事助手——顺便讲清楚 RAG 在「实时数据」场景的真实边界
别迷信「AI 算出冠军」的标题党,预测足球比分本质是个带大量噪声的回归问题,这篇带你把它拆清楚
从半自动越位技术到 AI 自动生成集锦,拆解足球视频分析背后的 CV 技术栈和工程难点
一场比赛的解说,怎么实时转成几十种语言的字幕?拆解 ASR + 翻译 + 时间轴对齐的工程链路
职业球队怎么用 AI 拆解对手?把比赛录像变成跑位热图、传球网络、防守阵型的完整技术路径