进阶 📋 6 个步骤 第 401 / 470 篇

用 AI 把自然语言变成 SQL 查询:不懂 SQL 也能查数据库

用大白话让 AI 生成 SQL,从单表统计到多表 JOIN 与聚合。讲清为什么要给表结构、如何核对生成语句、以及防 AI 瞎编列名与连只读库的安全清单。

2026.09.09· 15 分钟阅读· 约 1036 字· 🗄️ SQLite / 🧠 DeepSeek

「帮我查一下上个月消费最高的 5 个用户」——这种问题,过去得会写 SQL。现在你可以直接用中文问 AI,让它写出查询语句。这叫 text-to-SQL。本教程带你从建库、给结构、问问题,到把查询固化成小工具,全程强调「核对」,避免 AI 一本正经地胡写。

🗄️ 本教程适合:运营、产品、分析师等「想查数据但不熟 SQL」的同学;也适合开发者做快速原型。

先搞懂:为什么必须给 AI 看「表结构」?

AI 不知道你数据库里有什么表、列叫什么。如果你只说「查消费最高的用户」,它只能凭空猜列名,十有八九写出错 SQL。把表结构(schema)连同问题一起给它,是 text-to-SQL 成功的关键。

只给问题给问题 + schema
AI 瞎编 users / orders 表AI 按真实表名列名写
易报「表不存在」查询能直接跑通

Step 1:准备一个示例数据库

1 先有表,AI 才有依据

用轻量的 SQLite 建两张表当练习场:

import sqlite3
con = sqlite3.connect("demo.db")
con.executescript('''
CREATE TABLE users(id INTEGER, name TEXT, city TEXT);
CREATE TABLE orders(id INTEGER, user_id INTEGER, amount REAL, day TEXT);
INSERT INTO users VALUES(1,'小红','北京'),(2,'小明','上海');
INSERT INTO orders VALUES(1,1,199.0,'2026-08-01'),(2,1,59.0,'2026-08-02'),(3,2,320.0,'2026-08-01');
''')
con.commit()
💡 真实项目里,把 schema(建表语句)导出一份给 AI 即可,不必给数据本身。

Step 2:把「表结构 + 问题」一起给 AI

2 上下文给足,SQL 才靠谱

关键提示词模板:

你是一个 SQL 专家。下面是表结构:

CREATE TABLE users(id, name, city);
CREATE TABLE orders(id, user_id, amount, day);

请用 SQLite 语法回答:「每个城市有多少用户?」
只输出 SQL,不要解释。

指定方言:MySQL、PostgreSQL、SQLite 的语法有差异(如日期函数、分页)。一定写明你要哪种,否则 AI 可能混用。

Step 3:单表查询起步

3 先搞定「一张表」

问法越具体,SQL 越准。比如:

问题:统计每个城市的用户数
→ SELECT city, COUNT(*) FROM users GROUP BY city;

问题:消费金额大于 100 的订单有哪些
→ SELECT * FROM orders WHERE amount > 100;
🔍 新手建议从单表 WHERE / GROUP BY 起步,确认 AI 写对了再上复杂查询。

Step 4:多表 JOIN 与聚合

4 跨表关联才显威力

「消费最高的前 5 名用户及其订单数」需要连表:

SELECT u.name, SUM(o.amount) AS total, COUNT(o.id) AS orders
FROM users u
JOIN orders o ON o.user_id = u.id
GROUP BY u.id
ORDER BY total DESC
LIMIT 5;

JOIN 条件要对:连错字段会得到翻倍或空的怪结果。让 AI 解释它的 JOIN 逻辑,确认关联键无误。

Step 5:核对 AI 生成的 SQL(最重要的一步)

5 先在小库试跑,别直接上生产

AI 可能「幻觉」出不存在的列。上线前务必:

1. 在测试库 / 样本数据上先跑,看结果是否合理
2. 逐列核对:SQL 里的列名是否真在你的表里
3. 对聚合结果做个「手算抽查」(如总数是否对得上)
4. 只读查询用只读账号;禁止 AI 生成的写操作直接跑
✅ 经验法则:AI 写的 SQL 默认当「草稿」,你验证过才执行。涉及 UPDATE/DELETE 更要人工复核。

Step 6:固化成可复用小工具

把「中文→SQL→结果」做成一个脚本,以后只改问题:

import sqlite3, os
from openai import OpenAI
client = OpenAI(api_key=os.environ.get("DEEPSEEK_API_KEY"),
                base_url="https://api.deepseek.com")
SCHEMA = "CREATE TABLE users(id,name,city); CREATE TABLE orders(...);"

def ask(q):
    prompt = f"表结构:\n{SCHEMA}\n用SQLite回答:{q}\n只输出SQL"
    sql = client.chat.completions.create(
        model="deepseek-chat",
        messages=[{"role":"user","content":prompt}]).choices[0].message.content
    con = sqlite3.connect("demo.db")
    return con.execute(sql).fetchall()  # 仅只读查询

安全清单:连只读副本;禁止 AI 生成写操作直跑;含个人信息的数据先脱敏;生产库绝不暴露给公网模型。

常见问题速查

现象大概率原因 & 解决
报错「no such column」AI 编了列名;把真实 schema 给它
结果数量翻倍JOIN 键写错导致笛卡尔积
语法报错方言不对;明确要 SQLite/MySQL 等
怕误改数据只用只读账号跑 SELECT
← 返回教程中心