从JSON到SQL:基于业务场景的SQL生成器实战

news2025/4/19 1:36:52

引言

在数据驱动的业务场景中,将业务需求快速转化为SQL查询是常见需求。本文将通过一个轻量级的sql_json_to_sql函数,展示如何将JSON格式的查询描述转换为标准SQL语句,并结合实际业务场景验证其功能。


核心代码解析

1. 代码实现

def sql_json_to_sql(sql_json):
    """
    将扩展后的 sql_json 转换为完整的 SQL 语句
    :param sql_json: 生成的 sql_json 字典
    :return: 对应的 SQL 语句字符串
    """
    sql = []

    # 构建基础 SELECT 和 FROM
    select_clause = f"SELECT {', '.join(sql_json['select'])}"
    from_clause = f"FROM {sql_json['from']}"
    sql.append(select_clause)
    sql.append(from_clause)

    # 处理 JOIN
    if sql_json.get("joins"):
        join_clauses = []
        for join in sql_json["joins"]:
            join_type = join["type"].upper()
            table = join["table"]
            on_cond = join["on"]
            join_clauses.append(f"{join_type} JOIN {table} ON {on_cond}")
        sql.append(' '.join(join_clauses))

    # 处理 WHERE 条件
    if sql_json.get("conds"):
        where_conditions = []
        for cond in sql_json["conds"]:
            field, op, value = cond
            if isinstance(value, str) and not value.isdigit():
                value = f"'{value}'"
            where_conditions.append(f"{field} {op} {value}")
        if where_conditions:
            sql.append(f"WHERE {' AND '.join(where_conditions)}")

    # 处理 GROUP BY 和 HAVING
    if sql_json.get("group_by"):
        sql.append(f"GROUP BY {', '.join(sql_json['group_by'])}")
    if sql_json.get("having"):
        sql.append(f"HAVING {' AND '.join(sql_json['having'])}")

    # 处理 ORDER BY
    if sql_json.get("order_by"):
        order_expressions = [' '.join(ob) for ob in sql_json["order_by"]]
        sql.append(f"ORDER BY {', '.join(order_expressions)}")

    # 处理 LIMIT
    if sql_json.get("limit"):
        sql.append(f"LIMIT {sql_json['limit']}")

    return ' '.join([s for s in sql if s]).strip()

2. 核心功能

  • 基础查询SELECT, FROM
  • 联接操作:支持 INNER JOINLEFT JOIN
  • 条件过滤WHERE 条件组合(AND
  • 聚合与分组GROUP BY + HAVING
  • 排序与分页ORDER BY + LIMIT

测试案例与业务场景

案例1:销售分析 - 筛选高销量车系

业务场景

销售团队需要快速查看2024年各车系销量排名,辅助销售策略制定。

输入JSON
{
  "select": ["车系", "销量"],
  "conds": [["年", "==", "2024"]],
  "from": "即席查询",
  "order_by": [["销量", "DESC"]],
  "limit": 10
}
输出SQL
SELECT 车系, 销量 
FROM 即席查询 
WHERE== '2024' 
ORDER BY 销量 DESC 
LIMIT 10
表结构
字段名类型说明
车系VARCHAR(50)车系名称(如“SUV”)
销量INT年度销量数值
VARCHAR(4)销售年份(如“2024”)

案例2:员工信息报告 - 跨表聚合

业务场景

HR部门需要生成各部门员工信息报告,按部门分组并排序。

输入JSON
{
  "select": ["部门", "JSON_OBJECTAGG(员工ID, 姓名) AS 员工信息"],
  "from": "员工表",
  "joins": [
    {"type": "INNER JOIN", "table": "部门表", "on": "员工表.部门ID = 部门表.ID"}
  ],
  "group_by": ["部门"],
  "order_by": [["部门", "ASC"]],
  "limit": 5
}
输出SQL
SELECT 部门, JSON_OBJECTAGG(员工ID, 姓名) AS 员工信息 
FROM 员工表 
INNER JOIN 部门表 ON 员工表.部门ID = 部门表.ID 
GROUP BY 部门 
ORDER BY 部门 ASC 
LIMIT 5
表结构
  • 员工表

    字段名类型说明
    员工IDVARCHAR(20)员工唯一标识
    姓名VARCHAR(50)员工姓名
    部门IDVARCHAR(20)所属部门的外键
  • 部门表

    字段名类型说明
    IDVARCHAR(20)部门唯一标识(主键)
    部门VARCHAR(50)部门名称(如“销售部”)

案例3:日志分析 - JSON路径查询

业务场景

运维团队分析系统日志中的错误级别分布,定位高频问题。

输入JSON
{
  "select": ["JSON_VALUE(log, '$.severity') AS severity_level", "COUNT(*) AS log_count"],
  "from": "WebSite.Logs",
  "conds": [["JSON_VALUE(log, '$.severity')", "==", "P4"]],
  "group_by": ["severity_level"],
  "order_by": [["log_count", "DESC"]],
  "limit": 10
}
输出SQL
SELECT JSON_VALUE(log, '$.severity') AS severity_level, COUNT(*) AS log_count 
FROM WebSite.Logs 
WHERE JSON_VALUE(log, '$.severity') == 'P4' 
GROUP BY severity_level 
ORDER BY log_count DESC 
LIMIT 10
表结构
字段名类型说明
logJSON日志内容(如 {"severity": "P4", "message": "..."}

案例4:订单分析 - 复合条件与分组过滤

业务场景

财务部门分析2024年非西藏地区高销售额订单,排除边缘地区。

输入JSON
{
  "select": ["订单ID", "SUM(金额) AS 总销售额"],
  "from": "订单表",
  "conds": [["年份", "==", "2024"], ["省份", "!=", "西藏"]],
  "group_by": ["订单ID"],
  "having": ["总销售额 > 10000"],
  "order_by": [["总销售额", "DESC"], ["订单ID", "ASC"]],
  "limit": 20
}
输出SQL
SELECT 订单ID, SUM(金额) AS 总销售额 
FROM 订单表 
WHERE 年份 == '2024' AND 省份 != '西藏' 
GROUP BY 订单ID 
HAVING 总销售额 > 10000 
ORDER BY 总销售额 DESC, 订单ID ASC 
LIMIT 20
表结构
字段名类型说明
订单IDVARCHAR(20)订单唯一标识
金额DECIMAL(10,2)订单总金额
年份VARCHAR(4)订单年份(如“2024”)
省份VARCHAR(20)订单所属省份

案例5:产品分析 - 聚合与HAVING过滤

业务场景

产品团队分析高价位产品类别,定位高端市场。

输入JSON
{
  "select": ["产品类别", "AVG(价格) AS 平均价格"],
  "from": "产品表",
  "group_by": ["产品类别"],
  "having": ["AVG(价格) > 1000"],
  "order_by": [["平均价格", "ASC"]]
}
输出SQL
SELECT 产品类别, AVG(价格) AS 平均价格 
FROM 产品表 
GROUP BY 产品类别 
HAVING AVG(价格) > 1000 
ORDER BY 平均价格 ASC
表结构
字段名类型说明
产品IDVARCHAR(20)产品唯一标识
产品类别VARCHAR(50)产品分类(如“电子产品”)
价格DECIMAL(10,2)产品单价

扩展性与局限性

  1. 支持场景

    • 基础查询:SELECT、WHERE、ORDER BY、LIMIT
    • 复杂查询:JOIN、GROUP BY、HAVING、JSON函数
    • 多条件组合:AND 条件自动拼接
  2. 未来扩展方向

    • DML支持:INSERT、UPDATE、DELETE
    • 数据库适配:支持不同数据库的方言(如MySQL、PostgreSQL)
    • 参数化查询:防止SQL注入,支持预编译语句

总结

通过将JSON描述转换为SQL语句,可以快速将业务需求转化为可执行的查询,提升开发效率。本文提供的工具和案例覆盖了销售分析、日志监控、订单统计等典型场景,帮助开发者在实际业务中灵活应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2336152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SOME/IP中”客户端消费“及”服务端提供”的解析

先上结论 AREthAddConsumedEventGroup-->客户端的函数-->谁调用 Consumed函数,谁就是消费者 AREthAddProvidedEventGroup-->服务端的函数-->谁调用 Provided函数,谁就是服务端 Server 端:AREthAddProvidedEventGroup → 声明 &…

Linux 深入浅出信号量:从线程到进程的同步与互斥实战指南

知识点1【信号量概述】 信号量是广泛用于进程和线程间的同步和互斥。信号量的本质 是一个非负的整数计数器,它被用来控制对公共资源的访问 当信号量值大于0的时候,可以访问,否则将阻塞。 PV原语对信号量的操作,一次P操作使信号…

Oracle数据库数据编程SQL<9.1 数据库逻辑备份和迁移exp和imp之导出、导入>

EXP (Export) 和 IMP (Import) 是 Oracle 提供的传统数据导出导入工具,用于数据库逻辑备份和迁移。尽管在较新版本中已被 Data Pump (EXPDP/IMPDP) 取代,但在某些场景下仍然有用。 目录 一、EXP 导出工具 1. 基本语法 2. 常用参数说明 3. 导出模式 3.1 表模式导出 3.2 用…

DotnetCore开源库SampleAdmin源码编译

1.报错: System.Net.Sockets.SocketException HResult0x80004005 Message由于目标计算机积极拒绝,无法连接。 SourceSystem.Net.Sockets StackTrace: 在 System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, C…

.Net 9 webapi使用Docker部署到Linux

参考文章连接: https://www.cnblogs.com/kong-ming/p/16278109.html .Net 6.0 WebApi 使用Docker部署到Linux系统CentOS 7 - 长白山 - 博客园 项目需要跨平台部署,所以就研究了一下菜鸟如何入门Net跨平台部署,演示使用的是Net 9 webAPi Li…

PyTorch 根据官网命令行无法安装 GPU 版本 解决办法

最近遇到一个问题,PyTorch 官网给出了 GPU 版本的安装命令,但安装成功后查看版本,仍然是 torch 2.6.0cpu 1. 清理现有 PyTorch 安装 经过探索发现,需要同时卸载 conda 和 pip 安装的 torch。 conda remove pytorch torchvision …

PHP防火墙代码,防火墙,网站防火墙,WAF防火墙,PHP防火墙大全

PHP防火墙代码,防火墙,网站防火墙,WAF防火墙,PHP防火墙大全 资源宝整理分享&#xff1a;https://www.htple.net PHP防火墙&#xff08;作者&#xff1a;悠悠楠杉&#xff09; 验证测试&#xff0c;链接后面加上?verify_cs1后可以自行测试 <?php //复制保存zzwaf.php$we…

使用 Vitis Model Composer 生成 FPGA IP 核

本文将逐步介绍如何使用 Vitis Model Composer 生成 FPGA IP 核&#xff0c;从建模到部署。 在当今快节奏的世界里&#xff0c;技术正以前所未有的速度发展&#xff0c;FPGA 设计也不例外。高级工具层出不穷&#xff0c;加速着开发进程。传统上&#xff0c;FPGA 设计需要使用硬…

BERT、T5、ViT 和 GPT-3 架构概述及代表性应用

BERT、T5、ViT 和 GPT-3 架构概述 1. BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09; 架构特点 基于 Transformer 编码器&#xff1a;BERT 使用多层双向 Transformer 编码器&#xff0c;能够同时捕捉输入序列中每个词的左右上下文信息…

倚光科技:以创新之光,雕琢全球领先光学设计公司

在光学技术飞速发展的当下&#xff0c;每一次突破都可能为众多领域带来变革性的影响。而倚光&#xff08;深圳&#xff09;科技有限公司&#xff0c;作为光学设计公司的一颗璀璨之星&#xff0c;正以其卓越的创新能力和深厚的技术底蕴&#xff0c;引领着光学设计行业的发展潮流…

数据结构(六)——红黑树及模拟实现

目录 前言 红黑树的概念及性质 红黑树的效率 红黑树的结构 红黑树的插入 变色不旋转 单旋变色 双旋变色 插入代码如下所示&#xff1a; 红黑树的查找 红黑树的验证 红黑树代码如下所示&#xff1a; 小结 前言 在前面的文章我们介绍了AVL这一棵完全二叉搜索树&…

解决 Vue 中 input 输入框被赋值后,无法再修改和编辑的问题

目录 需求&#xff1a; 出现 BUG&#xff1a; Bug 代码复现 解决问题&#xff1a; 解决方法1&#xff1a; 解决方法2 关于 $set() 的补充&#xff1a; 需求&#xff1a; 前段时间&#xff0c;接到了一个需求&#xff1a;在选择框中选中某个下拉菜单时&#xff0c;对应的…

【差分隐私相关概念】瑞丽差分隐私(RDP)-瑞丽散度约束了贝叶斯因子后验变化

分步解释和答案&#xff1a; 在Rnyi差分隐私&#xff08;RDP&#xff09;框架中&#xff0c;通过贝叶斯因子和Rnyi散度的关系可以推导出关于后验变化的概率保证。以下是关键步骤的详细解释&#xff1a; 1. 贝叶斯因子的定义与分解 设相邻数据集 D D D 和 D ′ D D′&#x…

前端快速入门——JavaScript函数、DOM

1.JavaScript函数 函数是一段可重复使用的代码块&#xff0c;它接受输入(参数)、执行特定任务&#xff0c;并返回输出。 <scricpt>function add(a,b){return ab;}let cadd(5,10);console.log(c); </script>2.JavaScript事件 JavaScript绑定事件的方法&#xff1…

10【模块学习】LCD1602(二):6路温度显示+实时时钟

项目&#xff1a;6路温度显示实时时钟 1、6路温度显示①TempMenu.c文件的代码②TempMenu.h文件的代码③main.c文件的代码④Timer.c文件的代码⑤Delay.c文件的代码⑥Key.c文件的代码 2、实时时钟显示①BeiJingTime.c文件的代码②BeiJingTime.h文件的代码③main.c文件的代码如下④…

PDF处理控件Aspose.PDF指南:使用 C# 从 PDF 文档中删除页面

需要从 PDF 文档中删除特定页面&#xff1f;本快速指南将向您展示如何仅用几行代码删除不需要的页面。无论您是清理报告、跳过空白页&#xff0c;还是在共享前自定义文档&#xff0c;C# 都能让 PDF 操作变得简单高效。学习如何以编程方式从 PDF 文档中选择和删除特定页面&#…

如何在不同版本的 Elasticsearch 之间以及集群之间迁移数据

作者&#xff1a;来自 Elastic Kofi Bartlett 当你想要升级一个 Elasticsearch 集群时&#xff0c;有时候创建一个新的独立集群并将数据从旧集群迁移到新集群会更容易一些。这让用户能够在不冒任何停机或数据丢失风险的情况下&#xff0c;在新集群上使用所有应用程序测试其所有…

Day08【基于预训练模型分词器实现交互型文本匹配】

基于预训练模型分词器实现交互型文本匹配 目标数据准备参数配置数据处理模型构建主程序测试与评估总结 目标 本文基于预训练模型bert分词器BertTokenizer&#xff0c;将输入的文本以文本对的形式&#xff0c;送入到分词器中得到文本对的词嵌入向量&#xff0c;之后经过若干网络…

npm和npx的作用和区别

npx 和 npm 是 Node.js 生态系统中两个常用的工具&#xff0c;它们有不同的作用和使用场景。 1. npm&#xff08;Node Package Manager&#xff09; 作用&#xff1a; npm 是 Node.js 的包管理工具&#xff0c;主要用于&#xff1a; 安装、卸载、更新项目依赖&#xff08;包&a…

C++学习之金融类安全传输平台项目git

目录 1.知识点概述 2.版本控制工具作用 3.git和SVN 4.git介绍 5.git安装 6.工作区 暂存区 版本库概念 7.本地文件添加到暂存区和提交到版本库 8.文件的修改和还原 9.查看提交的历史版本信息 10.版本差异比较 11.删除文件 12.本地版本管理设置忽略目录 13.远程git仓…