想用DeepSeek生成一条能直接跑的SQL,光靠一句“帮我查一下”是不够的——它可不会读你的数据库,也不会猜你的表名,更不懂“最近”“高价值”这种业务黑话。你得把实体、条件、字段、关联路径、方言全写明白,少一个就可能生成报错语句。下面这几条技巧,能帮你绕过它“不会猜”的短板。

提供完整表结构信息
DeepSeek无法自动获取真实数据库的元数据,所有字段名、类型、主外键关系都必须人工显式提供。否则它会按常见命名习惯虚构字段,比如把 user_id 猜成 id,把 order_time 写成 create_time,执行时直接报 【Unknown column】。
在提示词开头用代码块格式粘贴 CREATE TABLE 语句,例如:
CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50), phone VARCHAR(20), reg_time DATETIME);
CREATE TABLE orders (id INT PRIMARY KEY, user_id INT, amount DECIMAL(10,2), order_time DATETIME);
并在下方补充说明外键路径:【orders.user_id → users.id】。这一步不可省略,否则 DeepSeek 可能随机匹配 users.id = orders.id 这类明显错误的 JOIN 条件。
用三段式模板组织自然语言指令
固定结构能大幅降低模型自由发挥概率。按顺序写清【任务】【输入约束】【输出要求】三个模块,中间用空行分隔。
第一步:在【任务】中用动词开头,明确操作类型和业务目标,例如:“检索2024年5月下单金额超过500元的北京用户姓名、手机号、订单数”。
第二步:在【输入约束】里限定范围,例如:“仅使用 users 和 orders 表;时间字段统一用 order_time;用户地区以 users.city 字段为准”。
第三步:在【输出要求】中强制格式,例如:“只输出一条可执行 SELECT 语句,不带任何解释、不加 ```sql 标记、不换行”。
这一步漏掉“不加 ```sql 标记”,DeepSeek 常会返回带代码块包裹的 SQL,复制后需手动删标记才能执行。
显式声明数据库方言与函数语法
DeepSeek 不会根据上下文判断你用的是 MySQL 还是 PostgreSQL。“取年份”在 MySQL 写 DATE_FORMAT(order_time, '%Y'),在 PostgreSQL 必须写 EXTRACT(YEAR FROM order_time),混用必报错。
方法一:在提示词最开头直接注明,例如:“使用 PostgreSQL 语法,时间字段为 TIMESTAMPTZ 类型”。
方法二:在 VS Code 插件配置中预设 deepseek-coder.sql.dialect 为 postgresql(或 mysql/sqlserver)。
方法三:对时间范围类操作,必须写死函数调用形式。例如:“用 CURRENT_DATE - INTERVAL '30 days' 计算30天前日期”,不能只写“最近一个月”——【DeepSeek 不会自动转译模糊时间表述】。
用少样本(Few-shot)引导复杂逻辑
当查询涉及嵌套、CASE WHEN、窗口函数或特殊聚合时,一次性描述容易丢失细节。此时插入 2–3 组“自然语言→正确SQL”的配对示例最有效。
① 示例1:自然语言:“统计每个城市的活跃用户数(last_login_time 在30天内)” → SQL:“SELECT city, COUNT(*) FROM users WHERE last_login_time >= DATE_SUB(NOW(), INTERVAL 30 DAY) GROUP BY city”
② 示例2:自然语言:“按订单金额分三档:≤100为低,101–500为中,>500为高,统计各档订单数” → SQL:“SELECT CASE WHEN amount <= 100 THEN '低' WHEN amount BETWEEN 101 AND 500 THEN '中' ELSE '高' END AS level, COUNT(*) FROM orders GROUP BY level”
③ 在最后加一行分隔符:“--- 以上为示例,以下为待处理问题:”
这一步的关键是所有示例必须来自同一数据库环境,字段名、别名、函数风格保持一致,否则模型会混淆语法边界。
