CodeBuddy+SQLazy MCP 自动化编写和倒译复杂 SQL 实践
安装 SQLazy IDE
1. 从官网https://www.raqsoft.com.cn/download-SQLazy下载
2. 安装完后,启动 SQLazy IDE,
3. 点击【工具 / 内存表】,点【导入】,选择【例子数据.ndb】,这是本文用到的测试例句对应的数据,实际使用时请替换成自己的数据(后面章节会介绍测试数据的生成)。
注意:系统运行时,会自动读取内存表中的表结构、数据类型,并使用内存表中的数据测试结果代码,所以可以把测试数据造成内存表,供 Codebuddy 验证代码时使用。
4. 点击 【工具 / 启动 MCP 服务】
注意:如果替换了例子数据,需要重启 MCP 服务。
5. 安装完后,可以在安装目录下看到【SQLazy 安装目录】/MCP目录,打开此目录,可以看到内容如下:

在 Codebuddy 配置 SQLazy SKILL
1. 下载安装 CodeBuddy
2. 安装 SQLazy 的 SKILL:点击【文件 / 打开文件夹】,打开上一步中5提到的 SQLazy 文件夹
3. 在设置中 激活 / 启动 其中的 SQLazy-MCP
使用 SQLazy 编写 SQL
上述步骤都完成后,在 Codebuddy IDE 界面右下角的对话窗口里输入查询语句:
1. 先输入 /,此时会出现命令列表,滚动鼠标,选择SQLazy规划,输入查询目标:计算月销售额最长连续上涨了几个月?
2. 按回车,等待输出结果:

输出结果中除了输出思考过程、结果代码,还会最终输出交付字样,以及文件:……,表示 Codebuddy 最终把结果代码写入了这个文件中。
3. 从 SQLazy IDE 中打开这个文件:

点击【执行】后,可以看到最终的执行结果。
4. 编译 SQL:
点击【工具 / 数据连接】,连接到对应的数据库。
点击【程序 / 编译 SQL】:

先选择目标数据库类型,然后点击编译按钮:

可以看到 SQL 已经生成好了,然后点击执行按钮:

可以看到最终的结果是 4,和 SQLazy 的代码执行结果一致(前提是要保证内存表的数据和数据库里完全一致)。
测试数据生成
可以根据自己的业务需求,自动生成测试数据,系统会自动把测试数据同时写入 ndb 文件和SQLazy IDE当前连接的数据库,通过这种方式生成的测试数据,天然可以保证内存数据表和数据库一致。
*** 在生成测试数据之前,先保证已打开SQLazy IDE,且MCP服务在运行中 ***
操作步骤如下:
1. 在SQLazy IDE中点击【工具 / 数据连接】,连接到对应的数据库。
一定要确保显示:已连接
2. 在 Codebuddy 右下角对话框中先输入 /,在列出的命令中选择 生成测试用例:
在其后输入对测试数据表结构、数据逻辑的需求,比如:
/ 生成测试用例 生成如下的 8 张表:
- ** 地区 **: 地区 ID(数值), 地区名称 (字符串)
- ** 国家 **: 国家 ID(数值), 国家名称 (字符串), 地区 ID(数值)
- ** 零件 **: 零件 ID(数值), 零件名称 (字符串), 制造商名称 (字符串), 品牌 (字符串), 零件类型 (字符串), 尺寸规格 (数值), 包装方式 (字符串), 零售价 (数值)
- ** 供应商 **: 供应商 ID(数值), 供应商名称 (字符串), 供应商地址 (字符串), 国家 ID(数值), 供应商联系电话 (字符串), 供应商账户余额 (数值)
- ** 零件供应 **: 零件 ID(数值), 供应商 ID(数值), 库存量 (数值), 成本价 (数值)
- ** 客户 **: 客户 ID(数值), 客户名称 (字符串), 客户地址 (字符串), 国家 ID(数值), 客户联系电话 (字符串), 客户账户余额 (数值), 行业 (字符串)
- ** 订单 **: 订单 ID(数值), 客户 ID(数值), 订单状态 (字符串), 订单金额 (数值), 订单日期 (日期时间), 订单优先级 (字符串), 经办人 (字符串), 发货优先级 (数值)
- ** 订单明细 **: 订单 ID(数值), 零件 ID(数值), 供应商 ID(数值), 序号 (数值), 订购数量 (数值), 订购金额 (数值), 折扣率 (数值), 税率 (数值), 退货标记 (字符串), 发货状态 (字符串), 发货日期 (日期时间), 承诺到货日期 (日期时间), 实际到货日期 (日期时间), 发货指示 (字符串), 运输方式 (字符串)
其中订单数据大概每年 3000-5000 条,要求生成 2022-2026 年的,订单明细是订单表的明细子表,大概一条订单记录对应 1-5 条订单明细记录,两者以订单 ID 关联,其中的日期字段要有一定的相关性:比如发货日期肯定要晚于订单日期,承诺到货日期肯定要晚于发货日期,实际到货日期大部分和承诺发货日期接近。即这几个日期字段的值要符合业务逻辑上的相关性。
订单表的客户 ID 字段取值来源于客户表,两者通过客户 ID 字段关联,客户表是订单表的维表。
订单明细表的零件 ID 和供应商 ID 字段的取值来源于零件供应,两表通过零件 ID 和供应商 ID 字段关联,订单明细表中订购金额字段的取值,来源于零件供应关联记录的成本价,其等于成本价 *10%* 订购数量
零件供应的零件 ID 字段关联零件表的零件 ID 字段
零件供应的供应商 ID 字段关联供应商表的供应商 ID 字段
供应商表和客户表的国家 ID 字段关联国家表的国家 ID 字段
国家表的地区 ID 字段关联地区表的地区 ID 字段
3. 按回车后,等待结果提示:

从输出结果提示中可以找到类似上图中的内容,说明结果数据已经同时写入 ndb/ 供应链订单测试数据.ndb 文件和SQLazy IDE当前连接的数据库中,
6. 在 SQLazy IDE 中点击【工具 / 内存表】,点击【导入】按钮,选择 ndb/ 供应链订单测试数据.ndb 文件,可以看到:

7. 通过这种方式造的测试数据,可以确保在内存表中和数据库中是完全一致的,后面就可以测试把 SQL 翻译成 SQLazy 的功能,Codebuddy 会自动连接数据库和内存表,分别测试 SQL 和 SQLazy 的运行结果是否一致。
8. 特别注意:造数之前,数据库中有同名的表,会出现如下提示:
A 删除并替换
B 保留原表
C 自定义回答
如果不选会一直停留在这步等待。请根据需要选择。
同理,如果 ndb 目录下有同名的.ndb 文件,也会出现类似的提示,也请根据需要选择。

将 SQL 翻译成 SQLazy 代码
*** 在测试数本功能之前,先保证已打开SQLazy IDE,且MCP服务在运行中 ***
1. 在 SQLazy IDE 中点击【工具 / 数据连接】,连接上一步造测试数据用的数据库。
这里的数据库连接,是用来执行待翻译的 SQL,和 SQLazy 的运行结果对比,核对生成的代码是否正确。
*** 一定要保证数据库中的表结构、数据和内存表中的是一致的,尽量使用上一步造的测试数据,因为这样可以天然保证一致。***
2. 在右下角对话框中,先输入 /,然后在列表中选择 SQL 倒译,在后面输入 SQL 语句:

2. 按回车,等待结果:

输出结果里可以看到结果代码被写入到 nsql/……nsql 文件中,用 SQLazy IDE 打开此文件,即可执行。
还可以看到 SQL 的执行结果和.nsql 代码执行结果的对比,看看结果是否完全一致:

从结果提示中,可以看到.nsql 文件的执行结果和原 SQL 是一致的。
编写 SQL 案例
案例一:
输入:
/SQLazy 规划 计算月销售额最长连续上涨了几个月?
输出:
t1=订单:汇总 合计 订单金额 命名 月销售额 分组 ymonth(订单日期) 命名 年月
t2=t1:分段 月销售额 未变大 命名 段号
t3=t2:汇总 计数 段号 命名 连续上涨月数 分组 段号
t4=t3:汇总 最大 连续上涨月数 命名 最长连续上涨月数
案例二:
输入:
/SQLazy 规划 将 2025 年的销售总额 *1.05 作为 2026 年的销售目标,按国家分摊,国家按国家 ID 排序,每个国家的销售目标为 (2025 年的销售总额 *1.05)/ 国家总数,保留整数部分,截掉小数部分。尾差由排序第一的国家承担。
输出:
t1=客户:导出表 国家ID 唯一值
t2=t1:排序 国家ID
t3=订单:汇总 合计 订单金额 条件 year(订单日期)=2025 命名 销售总额
t4=t1:汇总 计数 国家ID 命名 国家总数
t5=计算 t3.销售总额*1.05
t6=计算 floor(t5/t4.国家总数)
t7=计算 t5-t4.国家总数*t6
t8=t2:排名 国家ID 命名 名次
t9=t8:计算列 条件(名次=1 则 t6+t7 否则 t6) 命名 销售目标
t10=t9:导出表 国家ID,销售目标
案例三:
输入:
/SQLazy 规划 将客户表、供应商表、零件表、订单表、订单明细表五个表按关联字段拼接成一张宽表。
要求:
每个 ID(客户 ID、供应商 ID、零件 ID、订单 ID)作为一行
合并后的字段包括:客户 ID、客户名称、国家 ID;供应商 ID、供应商名称、国家 ID;零件 ID、零件名称、品牌;订单 ID、订单金额、订单日期
如果某个 ID 在对应的原表中不存在,则相关字段取 NULL
输出:
t1=订单明细:拼接 订单ID 关联表 订单 订单ID 拼接列 订单金额,订单日期,客户ID 全连接
t2=t1:拼接 零件ID 关联表 零件 零件ID 拼接列 零件名称,品牌 全连接
t3=t2:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 供应商名称,国家ID 命名 供应商国家ID 全连接
t4=t3:拼接 客户ID 关联表 客户 客户ID 拼接列 客户名称,国家ID 命名 客户国家ID 全连接
t5=t4:导出表 客户ID,客户名称,客户国家ID,供应商ID,供应商名称,供应商国家ID,零件ID,零件名称,品牌,订单ID,订单金额,订单日期
案例四:
输入:
/SQLazy 规划 对订单数据按订单日期排序,以天为单位进行汇总。要求以滑动窗口方式统计:
从第一条记录开始,每天作为一个窗口的结束时间
每个窗口包含当天及其前 29 天(共 30 天)内的订单数据
统计每个窗口的:订单总数、订单总金额
窗口之间滑动步长为 1 天
只输出时间跨度大于 29 天的窗口
输出:
t1=订单:汇总 计数 订单ID 命名 每日订单数,合计 订单金额 命名 每日订单金额 分组 订单日期
t2=t1:计算列 合计 每日订单数[-29:0] 命名 订单总数; 合计 每日订单金额[-29:0] 命名 订单总金额; 计数 每日订单数[-29:0] 命名 窗口天数
t3=t2:筛选 窗口天数 >= 30
t4=t3:导出表 订单日期 命名 窗口结束日期,订单总数,订单总金额
案例五:
输入:
/SQLazy 规划 统计 2026 年各供应商供应的零件在各国家的销售情况,计算每个零件在国家内的销售占比、零件全球总销售额、国家内排名,最终取每个国家排名前三的零件,并计算与上一名零件的销售额差值。
输出:
t1=订单:筛选 year(订单日期)=2026
t2=订单明细:拼接 订单ID 关联表 t1 订单ID 拼接列 客户ID 内连接
t3=t2:拼接 零件ID 关联表 零件 零件ID 拼接列 零件名称
t4=t3:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 供应商名称
t5=t4:拼接 客户ID 关联表 客户 客户ID 拼接列 国家ID 命名 客户国家ID
t6=t5:汇总 合计 订购金额*(1-折扣率) 命名 销售额 分组 供应商ID,供应商名称,零件ID,零件名称,客户国家ID
t7=t6:计算列 合计 销售额 命名 国家总销售额 分区 客户国家ID
t8=t7:计算列 销售额/国家总销售额 命名 国家内销售占比
t9=t8:计算列 合计 销售额 命名 零件全球总销售额 分区 零件ID
t10=t9:排名 销售额 降序 命名 国家内排名 分区 客户国家ID
t11=t10:排序 客户国家ID,国家内排名
t12=t11:计算列 销售额[-1] 命名 上一名销售额 分区 客户国家ID
t13=t12:计算列 上一名销售额-销售额 命名 与上一名差值
t14=t13:筛选 国家内排名<= 3
t15=t14:导出表 客户国家ID 命名 国家,供应商ID,供应商名称,零件ID,零件名称,销售额,国家内销售占比,零件全球总销售额,国家内排名,上一名销售额,与上一名差值
案例六:
输入:
/SQLazy 规划 统计每个零件在各年份的销售情况,计算每个零件的年度同比销售额(与上一年度对比)和季度环比销售额(与上一季度对比),并计算对应的增长率百分比。
输出:
t1=订单明细:拼接 订单ID 关联表 订单 订单ID 拼接列 订单日期
t2=t1:拼接 零件ID 关联表 零件 零件ID 拼接列 零件名称
t3=t2:汇总 合计 订购金额*(1-折扣率) 命名 年销售额 分组 零件ID,零件名称,year(订单日期) 命名 年
t4=t3:计算列 年销售额 增长 命名 年度同比销售额; 年销售额 增长率 命名 年度同比增长率 分区 零件ID
t5=t4:计算列 round(年度同比增长率*100,2) 命名 年度同比增长率百分比
年度同比表=t5:导出表 零件ID,零件名称,年,年销售额,年度同比销售额,年度同比增长率百分比
t6=t2:汇总 合计 订购金额*(1-折扣率) 命名 季销售额 分组 零件ID,零件名称,year(订单日期) 命名 年,quarter(订单日期) 命名 季度
t7=t6:计算列 季销售额 增长 命名 季度环比销售额; 季销售额 增长率 命名 季度环比增长率 分区 零件ID
t8=t7:计算列 round(季度环比增长率*100,2) 命名 季度环比增长率百分比
季度环比表=t8:导出表 零件ID,零件名称,年,季度,季销售额,季度环比销售额,季度环比增长率百分比
翻译 SQL
1. TPC-H Q7:按国家、年份统计发货量与金额
sql
/SQL倒译 select
供应商国家.国家名称 as 供应商国家,
客户国家.国家名称 as 客户国家,
year(订单明细.发货日期) as 年份,
sum(订单明细.订购金额 * (1 - 订单明细.折扣率)) as 收入
from
订单明细
join 订单 on 订单明细.订单ID = 订单.订单ID
join 客户 on 订单.客户ID = 客户.客户ID
join 供应商 on 订单明细.供应商ID = 供应商.供应商ID
join 国家 as 供应商国家 on 供应商.国家ID = 供应商国家.国家ID
join 国家 as 客户国家 on 客户.国家ID = 客户国家.国家ID
where
(
(供应商国家.国家名称 = '法国' and 客户国家.国家名称 = '德国')
or (供应商国家.国家名称 = '德国' and 客户国家.国家名称 = '法国')
)
and 订单明细.发货日期 between '2022-01-01' and '2026-12-31'
group by
供应商国家.国家名称,
客户国家.国家名称,
year(订单明细.发货日期)
order by</p>
供应商国家.国家名称,
客户国家.国家名称,
year(订单明细.发货日期);
SQLazy
t1=订单明细:拼接 订单ID 关联表 订单 订单ID 拼接列 客户ID 内连接
t2=t1:拼接 客户ID 关联表 客户 客户ID 拼接列 国家ID 命名 客户国家ID 内连接
t3=t2:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 国家ID 命名 供应商国家ID 内连接
t4=t3:拼接 供应商国家ID 关联表 国家 国家ID 拼接列 国家名称 命名 供应商国家 内连接
t5=t4:拼接 客户国家ID 关联表 国家 国家ID 拼接列 国家名称 命名 客户国家 内连接
t6=t5:计算列 year(发货日期) 命名 年份
t7=t6:筛选 (年份 >= 2022) 且 (年份 <= 2026)
t8=t7:筛选 ((供应商国家 = "FRANCE") 且 (客户国家 = "GERMANY")) 或 ((供应商国家 = "GERMANY") 且 (客户国家 = "FRANCE"))
t9=t8:汇总 合计 订购金额*(1-折扣率) 命名 收入 分组 供应商国家,客户国家,年份
t10=t9:排序 供应商国家,客户国家,年份
2. TPC-H Q8:按国家、年份统计市场份额
sql
/SQL倒译 select
年份,
sum(case when 供应商国家.国家名称 = 'BRAZIL' then 金额 else 0 end) / sum(金额) as 市场份额
from
(
select
year(订单.订单日期) as 年份,
订单明细.订购金额 * (1 - 订单明细.折扣率) as 金额,
供应商国家.国家名称 as 供应商国家名称
from
订单明细
join 订单 on 订单明细.订单ID = 订单.订单ID
join 客户 on 订单.客户ID = 客户.客户ID
join 国家 as 客户国家 on 客户.国家ID = 客户国家.国家ID
join 地区 on 客户国家.地区ID = 地区.地区ID
join 供应商 on 订单明细.供应商ID = 供应商.供应商ID
join 国家 as 供应商国家 on 供应商.国家ID = 供应商国家.国家ID
join 零件 on 订单明细.零件ID = 零件.零件ID
where
地区.地区名称 = 'AMERICA'
and 订单.订单日期 between 2022-01-01' and 2026-12-31'
and 零件.零件类型 = 'PROMO PLATED STEEL'
) as 全部国家
group by
年份
order by
年份;
SQLazy
t1=订单明细:拼接 订单ID 关联表 订单 订单ID 拼接列 订单日期,客户ID 内连接
t2=t1:拼接 客户ID 关联表 客户 客户ID 拼接列 国家ID 命名 客户国家ID 内连接
t3=t2:拼接 客户国家ID 关联表 国家 国家ID 拼接列 地区ID 命名 客户地区ID 内连接
t4=t3:拼接 客户地区ID 关联表 地区 地区ID 拼接列 地区名称 内连接
t5=t4:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 国家ID 命名 供应商国家ID 内连接
t6=t5:拼接 供应商国家ID 关联表 国家 国家ID 拼接列 国家名称 命名 供应商国家名称 内连接
t7=t6:拼接 零件ID 关联表 零件 零件ID 拼接列 零件类型 内连接
t8=t7:计算列 year(订单日期) 命名 年份
t9=t8:筛选 (地区名称 = "AMERICA") 且 (年份 >= 2022) 且 (年份 <= 2026) 且 (零件类型 = "PROMO PLATED STEEL")
t10=t9:汇总 合计 订购金额*(1-折扣率) 命名 全部收入,合计 订购金额*(1-折扣率) 条件 供应商国家名称 = "BRAZIL" 命名 巴西收入 分组 年份
t11=t10:计算列 巴西收入/全部收入 命名 市场份额
t12=t11:排序 年份
t13=t12:导出表 年份,市场份额
3. TPC-H Q9:按国家、年份统计零件利润
sql
/SQL倒译 select
国家名称,
年份,
sum(利润) as 总利润
from
(
select
国家.国家名称 as 国家名称,
year(订单.订单日期) as 年份,
订单明细.订购金额 * (1 - 订单明细.折扣率)
- 零件供应.成本价 * 订单明细.订购数量 as 利润
from
订单明细
join 订单 on 订单明细.订单ID = 订单.订单ID
join 零件 on 订单明细.零件ID = 零件.零件ID
join 供应商 on 订单明细.供应商ID = 供应商.供应商ID
join 国家 on 供应商.国家ID = 国家.国家ID
join 零件供应
on 零件供应.零件ID = 订单明细.零件ID
and 零件供应.供应商ID = 订单明细.供应商ID
where
零件.零件名称 like '%轴%'
) as 利润表
group by
国家名称,
年份
order by
国家名称,
年份 desc;
SQLazy
t1=订单明细:拼接 订单ID 关联表 订单 订单ID 拼接列 订单日期 内连接
t2=t1:拼接 零件ID 关联表 零件 零件ID 拼接列 零件名称 内连接
t3=t2:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 国家ID 命名 供应商国家ID 内连接
t4=t3:拼接 供应商国家ID 关联表 国家 国家ID 拼接列 国家名称 内连接
t5=t4:拼接 零件ID 供应商ID 关联表 零件供应 零件ID 供应商ID 拼接列 成本价 内连接
t6=t5:计算列 year(订单日期) 命名 年份
t7=t6:筛选 (零件名称 有子串 "轴")
t8=t7:汇总 合计 订购金额*(1-折扣率)-成本价*订购数量 命名 总利润 分组 国家名称,年份
t9=t8:排序 国家名称,年份 降序
4. TPC-H Q20:找出有大量库存、且曾供应过特定零件的供应商
sql
/SQL倒译 select
供应商.供应商名称,
供应商.供应商地址
from
供应商
join 国家 on 供应商.国家ID = 国家.国家ID
where
供应商.供应商ID in (
select
零件供应.供应商ID
from
零件供应
where
零件供应.零件ID in (
select
零件.零件ID
from
零件
where
零件.零件名称 like '%轴%'
)
and 零件供应.库存量 > (
select
0.5 * sum(订单明细.订购数量)
from
订单明细
where
订单明细.零件ID = 零件供应.零件ID
and 订单明细.供应商ID = 零件供应.供应商ID
and 订单明细.发货日期 >= '2022-01-01'
and 订单明细.发货日期 < '2026-01-01'
)
)
and 国家.国家名称 = 'CANADA'
order by
供应商.供应商名称;
SQLazy
t1=零件:筛选 (零件名称 串匹配 "%轴%")
t2=订单明细:筛选 (发货日期 >= 2022年01月01日) 且 (发货日期 < 2026年01月01日)
t3=t2:汇总 合计 0.5*订购数量 命名 阈值 分组 零件ID,供应商ID
t4=零件供应:拼接 零件ID 供应商ID 关联表 t3 零件ID 供应商ID 拼接列 阈值 内连接
t5=t4:筛选 库存量 > 阈值
t6=t5:匹配 零件ID 关联表 t1 零件ID
t7=t6:去重 供应商ID
t8=t7:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 供应商名称,供应商地址,国家ID 内连接
t9=t8:拼接 国家ID 关联表 国家 国家ID 拼接列 国家名称 内连接
t10=t9:筛选 国家名称 = "CANADA"
t11=t10:导出表 供应商名称,供应商地址
t12=t11:排序 供应商名称
5. TPC-H Q21:找出发货延迟、且未按时完成的供应商
sql
/SQL倒译 select
供应商.供应商名称,
count(*) as 等待次数
from
订单明细 as 明细1
join 订单 on 明细1.订单ID = 订单.订单ID
join 供应商 on 明细1.供应商ID = 供应商.供应商ID
join 国家 on 供应商.国家ID = 国家.国家ID
where
订单.订单状态 = 'F'
and 明细1.实际到货日期 > 明细1.承诺到货日期
and exists (
select
1
from
订单明细 as 明细2
where
明细2.订单ID = 明细1.订单ID
and 明细2.供应商ID <> 明细1.供应商ID
)
and not exists (
select
1
from
订单明细 as 明细3
where
明细3.订单ID = 明细1.订单ID
and 明细3.供应商ID <> 明细1.供应商ID
and 明细3.实际到货日期 > 明细3.承诺到货日期
)
and 国家.国家名称 = 'SAUDI ARABIA'
group by
供应商.供应商名称
order by
等待次数 desc,
供应商.供应商名称;
SQLazy
明细副本=订单明细:排序 订单ID
t1=明细副本:筛选 实际到货日期 > 承诺到货日期
t2=t1:匹配 订单ID 关联表 明细副本 订单ID 条件 供应商ID@ <> 供应商ID
t3=t2:匹配 订单ID 关联表 明细副本 订单ID 不存在 条件 (供应商ID@ <> 供应商ID) 且 (实际到货日期 > 承诺到货日期)
t4=t3:拼接 订单ID 关联表 订单 订单ID 拼接列 订单状态 内连接
t5=t4:筛选 订单状态 = "F"
t6=t5:拼接 供应商ID 关联表 供应商 供应商ID 拼接列 供应商名称,国家ID 内连接
t7=t6:拼接 国家ID 关联表 国家 国家ID 拼接列 国家名称 内连接
t8=t7:筛选 国家名称 = "SAUDI ARABIA"
t9=t8:汇总 计数 订单ID 命名 等待次数 分组 供应商名称
t10=t9:排序 等待次数 降序,供应商名称
