本文介绍了在使用NL2SQL时,为了达到预期效果,需要针对性规范表信息、配置项信息和问句的内容。
表信息规范
表的schema信息是使用NL2SQL的基础,表的schema信息覆盖要全(表注释、列注释、表之间的关联关系等),内容简洁清晰。
表注释
表注释能够帮助NL2SQL模型更好地理解表的基础信息,能更好地定位SQL语句中涉及的表。注释可以简洁明了地说明表的大致内容。如“订单”、“库存”等,尽量控制在7个字以内,不要引入过多解释。
列注释
-
列注释由用户常用的名词或名词短语构成。例如:“订单编号”、“日期”、“店铺名称”等,能精确体现列名所表达的含义。
-
不在列的注释中添加列的样例数据。
-
列注释之间需要有明显差异。例如:“订单编号”、“下单时间”,而不能是“周出勤率”、“月出勤率”这种很相近的词,相近的词在查询时容易判断错误。如果一张表中包含这些相近的列,需要删除这些列。若保留,则需要使用其他具有差异性的表达方式。
主外键说明
如果表之间存在多表关联关系,需要在表中建立主外键关系。这种关系能在表之间构造一个默认的联系,对生成SQL语句至关重要。
配置项规范
配置项中能力最强的是当config_type
参数值为1时可以配置“领域术语”,用户可以使用该配置参数对领域同义词进行扩展说明,以适配不同需求。
如用户提问“销冠”相关的数据,一般来说,算法是无法理解该缩略词。“销冠”表示销售冠军,对应的解释可能为“销售量排名最高的店员”或“总销售金额排名最高的店员”,这时就可以通过相应的配置来进行扩展,扩展词尽量控制在3个以内。更多详情请参见配置项。
问句规范
使用NL2SQL功能时,提出的问题中要明确表达出限制条件和相关的实体值。同时,尽量将条件前置,然后是需要找的列值对应的实体,最后是可能的列名。示例如下:
超过1个房间的“房子”或“公寓”的属性名称是什么?
其中,“超过1个房间”是条件,“房子”和“公寓”是列值对应的实体,属性名称是可能的列名。
推荐的问句样例如下:
-
进行过两次或更多次治疗的专家的ID、角色和名字是什么?
-
被养最多数量狗的品种名称是什么?
-
被喂养最多数量的狗都有哪些品种?给我这个品种的名字。
-
哪一位主人为他或她的狗支付了最多的治疗费?列出主人的ID和姓氏。
-
告诉我花在他或她的狗身上最多治疗费的主人的ID和姓氏。
-
总花费最少的治疗类型的描述是什么?
-
请给我描述一下总花费最低的治疗类型。
-
哪一个主人为他们的狗支付了最多的钱?显示主人的ID和邮政编码。
-
找出总计为他或她的狗花了最多钱的主人的ID和邮政编码。
-
哪些专家至少做过两种治疗?列出他们的专业ID和手机号码。
-
找出做过两种或更多种治疗的专业人员的ID和手机号码。
-
治疗费用低于平均的专家的名字和姓氏是什么?
-
哪些专家的治疗费用低于平均水平?给出名字和姓氏。
-
哪些狗是在“山西”的人拥有的?列出主人的名字和狗的名字。
-
找出居住在“山西”的主人的名字和他们拥有的狗的名字。
-
计算经过治疗的狗的数量。
-
有多少专家对狗进行过治疗?
-
在投资公司的融资额最多1000万时,给出企业的中文名以及企业的注册资本投资公司的投资公司。
-
哪些坚果中国人均消费的占比不小于2%,且坚果的不饱和脂肪含量不大于33克,同时给出这些坚果的饱和脂肪含量的最小值,以及坚果中国人均消费的消费次数的最大值。
-
年龄不大于25岁的篮球运动员中,哪5个运动员的生涯之最数量最多?并给出他们的场上位置。
-
在各球队欧冠赛事记录中,当球队欧冠赛事的净胜球的平均值等于100时,给出球队的中文队名以及球队欧冠赛事的届数的最小值。
示例
以某个销售场景为例来说明表信息规范和问句规范,假设用户有production_sales
和production_purchase
两张表。
规范化前的表信息如下:
-
production_sales
CREATE TABLE `production_sales` ( `record_date` datetime DEFAULT NULL COMMENT '日期', `dealer_provinces` varchar(20) DEFAULT NULL COMMENT '省区。例如"四川省区"、"大广东省区"等等', `dealer_area` varchar(20) DEFAULT NULL COMMENT '区域。如"营山"、"中山市区"', `dealer_number` varchar(20) DEFAULT NULL COMMENT '经销商的唯一编码', `dealer_name` varchar(20) DEFAULT NULL COMMENT '经销商名称', `brand` varchar(20) DEFAULT NULL COMMENT '品牌名称', `classify` varchar(20) DEFAULT NULL COMMENT '品类名称', `series` varchar(20) DEFAULT NULL COMMENT '营销系列', `sku` varchar(20) DEFAULT NULL COMMENT 'sku', `sale_total` float DEFAULT NULL COMMENT '销售金额', `sale_count` float DEFAULT NULL COMMENT '销售量' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='销售记录表(昨天、今天)'; SET FOREIGN_KEY_CHECKS = 1;
-
production_purchase
CREATE TABLE `production_purchase` ( `record_date` datetime DEFAULT NULL COMMENT '日期', `dealer_provinces` varchar(20) DEFAULT NULL COMMENT '省区。例如"四川省区"、"大广东省区"等等"', `dealer_area` varchar(20) DEFAULT NULL COMMENT '区域。如"营山"、"中山市区"', `dealer_number` varchar(20) DEFAULT NULL COMMENT '经销商的唯一编码', `dealer_name` varchar(20) DEFAULT NULL COMMENT '经销商名称', `brand` varchar(20) DEFAULT NULL COMMENT '品牌名称', `classify` varchar(20) DEFAULT NULL COMMENT '品类名称', `series` varchar(20) DEFAULT NULL COMMENT '营销系列', `sku` varchar(20) DEFAULT NULL COMMENT 'sku', `purchase_total` float DEFAULT NULL COMMENT '进货金额', `purchase_count` float DEFAULT NULL COMMENT '进货量' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='购买记录表(每天的数据)'; SET FOREIGN_KEY_CHECKS = 1;
按照规范修改表注释和列注释:
-
表注释
-
将“销售记录表(昨天、今天)”修改为“销售记录”。
-
将“购买记录表(每天的数据)”修改为“购买记录”。
-
-
列注释
-
将“经销商的唯一编码”修改为“经销商编码”。
-
将“省区,例如“四川省区”、“大广东省区”等等”修改为“省区”。
-
将“区域,如“营山”、“中山市区””改为“区域”。
-
将“品类名称”修改为“类别名称”。与“品牌名称”区分开。
-
实际使用过程中,用户基本不会问series相关的问题,故将
series
列删除。
-
规范化后的表信息如下:
-
production_sales
CREATE TABLE `production_sales` ( `record_date` datetime DEFAULT NULL COMMENT '日期', `dealer_provinces` varchar(20) DEFAULT NULL COMMENT '省区', `dealer_area` varchar(20) DEFAULT NULL COMMENT '区域', `dealer_number` varchar(20) DEFAULT NULL COMMENT '经销商编码', `dealer_name` varchar(20) DEFAULT NULL COMMENT '经销商名称', `brand` varchar(20) DEFAULT NULL COMMENT '品牌名称', `classify` varchar(20) DEFAULT NULL COMMENT '类别名称', `sku` varchar(20) DEFAULT NULL COMMENT 'sku', `sale_total` float DEFAULT NULL COMMENT '销售金额', `sale_count` float DEFAULT NULL COMMENT '销售量' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='销售记录'; SET FOREIGN_KEY_CHECKS = 1;
-
production_purchase
CREATE TABLE `production_purchase` ( `record_date` datetime DEFAULT NULL COMMENT '日期', `dealer_provinces` varchar(20) DEFAULT NULL COMMENT '省区', `dealer_area` varchar(20) DEFAULT NULL COMMENT '区域', `dealer_number` varchar(20) DEFAULT NULL COMMENT '经销商编码', `dealer_name` varchar(20) DEFAULT NULL COMMENT '经销商名称', `brand` varchar(20) DEFAULT NULL COMMENT '品牌名称', `classify` varchar(20) DEFAULT NULL COMMENT '类别名称', `sku` varchar(20) DEFAULT NULL COMMENT 'sku', `purchase_total` float DEFAULT NULL COMMENT '进货金额', `purchase_count` float DEFAULT NULL COMMENT '进货量' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='购买记录'; SET FOREIGN_KEY_CHECKS = 1;
小结
NL2SQL属于AI算法,AI算法的效果与诸多因素有关。为了使得查询结果不脱离预期,总结了可能会影响整体准确率的几个因素:
-
表和列注释的丰富程度。
每张表及表中的列都添加注释,会提高查询的准确率。
-
用户问题与表中列注释的匹配程度。
用户问题中的关键词和列注释保持一致,语义上越接近查询效果越好。
-
生成的SQL语句长度。
SQL语句中涉及的列越少、条件越简单查询会越准确。
-
SQL语句中的逻辑复杂程度。
SQL语句中涉及的高级语法越少查询越准确。