LLM在Text2SQL阶段仍受“幻觉”困扰,准确性问题尚未解决,无力向后端复杂分析延伸
多维分析是一连串有状态的操作序列,缺乏相关训练数据的LLM,难以可靠规划和执行整个流程

规范文本采用业务人员熟悉的自然语言,使用户能够直观确认查询意图,确认环节是解决幻觉问题的关键
规范文本遵循预定义的结构与词汇表,具备极强的机器可解析性,为支撑复杂查询奠定了基础
| 类别 | 说明 | 解释与示例 |
|---|---|---|
| 表与实体 |
表是数据库中的物理表。 实体是表的业务化视图,可定义不同的字段和过滤条件 |
• 示例:物理表销售订单可以定义两个实体: - “全部订单”:包含所有字段 - “本年新订单”:仅包含Year(签单日期)=Year(Now())的订单,并只显示订单ID、金额等核心字段 |
| 宏字段 | 查询的最小语义单元,是基础字段的扩展 |
• 基础字段:直接映射到表字段,如“订单金额” • 计算字段:通过表达式定义,如BMI指数 = (体重(kg) / 身高(m)²) • 外键字段:通过关联引入其他表信息,如通过“客户ID”引入“客户名称” |
| 指标 | 通过表达式定义的聚合度量,用于统计分析 |
• 简单指标:如“销售总额”(SUM)。 • 复杂指标(SPL):处理SQL不擅长的计算,如“用户留存率”、“股票连涨天数” |
| 字段簇与簇词 |
字段簇是一组业务紧密相关的字段集合 簇词是字段簇的业务别名,用于消除歧义 |
• 示例:定义“发货”簇(含城市、日期)和“收货”簇(含城市、日期)。 • 应用:用户说“发货 日期”,引擎能精准定位到“发货日期”,而不会与“签单日期”混淆 |
| 维、维词与常数词 | 维是分析视角,维词是其业务名,常数词将业务值映射到底层编码 |
• 示例:将“北京”、“上海”定义为“城市”维的常数词,映射到内部编码(30101, 30102) • 应用:用户查询“籍贯 北京 的雇员”,引擎自动转换为HOMECITY=30101 |
| 类别 | 说明 | 解释与示例 |
|---|---|---|
| 无效词 | 过滤掉查询中的口语化虚词和语气词,使引擎聚焦于有效信息 |
• 示例:“请帮我查一下”、“有哪些”、“那个”。 • 应用:用户输入“请帮我查一下有哪些销售额高的商品”,引擎会忽略加粗部分,直接解析核心意图 |
| 宏词 | 将口语化的业务概念转换为规范的查询过滤逻辑 |
• 示例:将“已售罄”定义为宏词,其背后逻辑是“库存量 <= 0” • 应用:用户查询“已售罄的商品”,引擎自动转换为库存量 <= 0 |
| 动词 | 用于建立复杂的过滤逻辑,特别是关联多个字段簇 |
• 示例:定义动词“发往”,将其左侧关联到“发货”簇,右侧关联到“收货”簇。 • 应用:用户查询“北京 发往 青岛 的订单”,被解析为发货城市=北京 AND 收货城市=青岛。 |
| 量词 | 用于处理带单位的数值,自动进行单位换算 |
• 示例:定义量词“万元”,换算系数为10000。 • 应用:用户查询“金额大于 20万元”,引擎会自动转换为金额 > 20*10000 |
| 比较词与连词 | 定义过滤关系与条件间的逻辑连接 |
• 比较词:大于、小于、等于。 • 连词:且、或。 • 应用:支持“年龄大于 40 且 性别 等于 男”这样的复杂条件组合 |
SELECT T_1."NAME" "姓名", T_1."EMPID" "雇员编码", T_1."TITLE" "职务", T_1."BIRTHDATE" "出生日期", (YEAR(NOW)-YEAR(T_1."BIRTHDATE")- CASE WHEN MONTH(NOW)* 100 + DAY(NOW)>MONTH(T_1."BIRTHDATE")* 100 + DAY(T_1."BIRTHDATE") THEN 0 ELSE 1 END ) "年龄" FROM EMPLOYEE T_1 WHERE (T_1."EMPID" = 3)
SELECT T_1_1."SHIPCITY" "发货城市", T_1_2."CITYCODE" "客户城市", T_1_1."ORDERID" "订单编码", T_1_1."SIGNDATE" "签单日期", T_1_1."SHIPDATE" "发货日期", T_1_1."RECEIVEDATE" "收货日期", T_1_1."AMOUNT" "订单金额" FROM ORDERS T_1_1 LEFT JOIN CUSTOMER T_1_2 ON T_1_1."CUSTOMERID" = T_1_2."CUSTID" WHERE ((T_1_1."SHIPCITY" = 30101) AND(T_1_2."CITYCODE" = 20201))
SELECT 性别 ,…,ORDERS.sum(订单金额) AS 订单金额总和
FROM EMPLOYEE
WHERE (性别 ='女')
JOIN ORDERS
HAVING 订单金额总和 >20*10000
SELECT T_1."EMPID" "雇员编码", T_1."GENDER" "性别", T_1."NAME" "姓名", T_1."TITLE" "职务", T_1."BIRTHDATE" "出生日期", (YEAR(NOW)-YEAR(T_1."BIRTHDATE")- CASE WHEN MONTH(NOW)* 100 + DAY(NOW)>MONTH(T_1."BIRTHDATE")* 100 + DAY(T_1."BIRTHDATE") THEN 0 ELSE 1 END ) "年龄", T_2.F_2 "订单金额总和" FROM EMPLOYEE T_1 LEFT JOIN ( SELECT T_2."EMPLOYEEID" F_1,sum(T_2."AMOUNT") F_2 FROM ORDERS T_2 GROUP BY T_2."EMPLOYEEID") T_2 ON T_1."EMPID" = T_2.F_1 WHERE ((T_2.F_2>20)) AND ((T_1."GENDER" = '女'))
SELECT EMPLOYEE.count(雇员编码) AS 员工数,
PRODUCT.count(产品编码) AS 产品数,
ORDERS. 大订单数 () AS 大订单数
ON 省份
FROM EMPLOYEE BY 省份
JOIN PRODUCT BY 省份
JOIN ORDERS BY 省份
大订单数=(x=?1.max(订单金额)/2,?1.count(订单金额>=x))
SELECT COALESCE(T_1.F_1,T_2.F_1,T_3.F_1) "省",T_1.F_2 "员工数",T_2.F_2 "产品数",T_3.F_2 "订单数" FROM (SELECT T_1_2."PROVINCE" F_1, count(1) F_2 FROM EMPLOYEE T_1_1 LEFT JOIN CITY T_1_2 ON T_1_1."HOMECITY" = T_1_2."CITYCODE" GROUP BY T_1_2."PROVINCE") T_1 FULL JOIN ( SELECT T_2_3."PROVINCE" F_1, count(1) F_2 FROM PRODUCT T_2_1 LEFT JOIN SUPPLIER T_2_2 ON T_2_1."SUPPLIERID" = T_2_2."SUPPLIERID" LEFT JOIN CITY T_2_3 ON T_2_2."CITY" = T_2_3."CITYCODE" GROUP BY T_2_3."PROVINCE") T_2 ON T_1.F_1 = T_2.F_1 FULL JOIN ( SELECT T_3_2."PROVINCE" F_1, count(1) F_2 FROM ORDERS T_3_1 LEFT JOIN CITY T_3_2 ON T_3_1."SHIPCITY" = T_3_2."CITYCODE" GROUP BY T_3_2."PROVINCE") T_3 ON COALESCE(T_1.F_1,T_2.F_1)= T_3.F_1
| 对比维度 | NLQ | LLM |
|---|---|---|
| 核心逻辑 | 基于确定性规则,过程透明、稳定 | 基于概率的黑箱模型,内部逻辑不可知 |
| 调试与追溯 | 每一步可追溯、可解释,像程序调试一样定位问题 | 过程不可追溯,如同猜测一个“黑盒”为何出错 |
| 问题根源诊断 | 可快速精准定位:是缺少词条、配置不当,还是引擎BUG? | 难以诊断根源:是提示词问题、知识缺失,还是模型幻觉? |
| 优化与迭代 | 通过补充和修改词典配置即可修复,成本低,效果可预测 | 依赖大量成本进行再训练,效果难以预测和保证 |
| 可控性 | 高度可控,系统的行为由明确的规则定义和约束 | 缺乏可控性,生成结果不稳定,易出现意想不到的输出 |
SELECT 订单金额 as 订单金额,订单编码,客户名称,签单日期,发货日期,收货日期 FROM orders WHERE 订单金额>=1000
基于单一数据源且不涉及聚合计算:
SELECT orders.sum(订单金额) as 总金额 ON city as 城市 FROM orders BY 发货城市
引入了维度和聚合的概念:
SELECT
客户编码,客户名称,联系人,联系人职务,城市编码,
orders.count(DISTINCT 订单编码) AS 订单数,
orders.sum(订单金额) AS 总订单金额
FROM customer
JOIN orders
HAVING (订单数> 5)
处理复杂数据关系的能力:
SELECT orderdetail.count(DISTINCT 订单编码) as 订单总数,
website_event.sum(在线订单()) as 汇总在线订单数
ON ProductType as 类别
FROM orderdetail
BY 产品类别
JOIN website_event
BY 产品分类
更复杂的指标查询范式:
MQL并没有处理业务常见的多对一外键关联,这种情况如何处理?
SELECT 发货城市,收货城市,订单编码,客户名称,签单日期,发货日期,收货日期,订单金额 FROM orders WHERE (发货城市=30101) AND (收货城市=20201)
SELECT shipcity, customerid.citycode,orderid,customerid,signdate,shipdate,receivedate,amount FROM orders WHERE shipcity=30101 and customerid.citycode=20201
SELECT o.shipcity, c.citycode, o.orderid, o.customerid, o.signdate, o.shipdate, o.receivedate FROM orders o JOIN customer c ON o.customerid = c.id WHERE o.shipcity = 30101 AND c.citycode = 20201
DQL的能力与SQL相当,BI中的复杂计算场景会存在局限,如何应对?
定义大订单(订单金额超过最大金额 50% 的订单)指标:
汉语查询结果,直接进行汉语分析(分组汇总)