从JSON到SQL:基于业务场景的SQL生成器实战
引言
在数据驱动的业务场景中,将业务需求快速转化为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 和 FROMselect_clause = f"SELECT {', '.join(sql_json['select'])}"from_clause = f"FROM {sql_json['from']}"sql.append(select_clause)sql.append(from_clause)# 处理 JOINif 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 = condif 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 和 HAVINGif 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 BYif sql_json.get("order_by"):order_expressions = [' '.join(ob) for ob in sql_json["order_by"]]sql.append(f"ORDER BY {', '.join(order_expressions)}")# 处理 LIMITif 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 JOIN、LEFT 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
表结构
-
员工表
字段名 类型 说明 员工ID VARCHAR(20) 员工唯一标识 姓名 VARCHAR(50) 员工姓名 部门ID VARCHAR(20) 所属部门的外键 -
部门表
字段名 类型 说明 ID VARCHAR(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
表结构
| 字段名 | 类型 | 说明 |
|---|---|---|
| log | JSON | 日志内容(如 {"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
表结构
| 字段名 | 类型 | 说明 |
|---|---|---|
| 订单ID | VARCHAR(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
表结构
| 字段名 | 类型 | 说明 |
|---|---|---|
| 产品ID | VARCHAR(20) | 产品唯一标识 |
| 产品类别 | VARCHAR(50) | 产品分类(如“电子产品”) |
| 价格 | DECIMAL(10,2) | 产品单价 |
扩展性与局限性
-
支持场景
- 基础查询:SELECT、WHERE、ORDER BY、LIMIT
- 复杂查询:JOIN、GROUP BY、HAVING、JSON函数
- 多条件组合:AND 条件自动拼接
-
未来扩展方向
- DML支持:INSERT、UPDATE、DELETE
- 数据库适配:支持不同数据库的方言(如MySQL、PostgreSQL)
- 参数化查询:防止SQL注入,支持预编译语句
总结
通过将JSON描述转换为SQL语句,可以快速将业务需求转化为可执行的查询,提升开发效率。本文提供的工具和案例覆盖了销售分析、日志监控、订单统计等典型场景,帮助开发者在实际业务中灵活应用。
相关文章:
从JSON到SQL:基于业务场景的SQL生成器实战
引言 在数据驱动的业务场景中,将业务需求快速转化为SQL查询是常见需求。本文将通过一个轻量级的sql_json_to_sql函数,展示如何将JSON格式的查询描述转换为标准SQL语句,并结合实际业务场景验证其功能。 核心代码解析 1. 代码实现 def sql_j…...
空格键会提交表单吗?HTML与JavaScript中的行为解析
在网页开发中,理解用户交互细节对于提供流畅的用户体验至关重要。一个常见的问题是:空格键是否会触发表单提交?本文将通过一个简单的示例解释这一行为,并探讨如何使用HTML和JavaScript来定制这种交互。 示例概览 考虑以下HTML代…...
06 - 多线程-JUC并发编程-原子类(二)
上一章,讲解java (java.util.concurrent.atomic) 包中的 支持基本数据类型的原子类,以及支持数组类型的原子类,这一章继续讲解支持对实体类的原子类,以及原子类型的修改器。 还有最后java (java…...
vue3 实现谷歌登录
很多人都是直接在 index.html 文件中引入的,刚开始我也那样写但是谷歌的api只能调起一次后续就不会生效了 我的登录是个弹窗,写在app.vue 文件中 const isGoogleLoaded ref(true);onMounted(async () > {initialize(); }); // 初始化 const initi…...
SOME/IP中”客户端消费“及”服务端提供”的解析
先上结论 AREthAddConsumedEventGroup-->客户端的函数-->谁调用 Consumed函数,谁就是消费者 AREthAddProvidedEventGroup-->服务端的函数-->谁调用 Provided函数,谁就是服务端 Server 端:AREthAddProvidedEventGroup → 声明 &…...
GO语言入门:字符串处理1(打印与格式化输出)
13.1 打印文本 在 fmt 包中,Print 函数用于打印(输出)文本信息。依据输出目标的不同,Print 函数可以划分为三组,详见下表。 按应用目标分组函数说明将文本信息输出到标准输出流,一般是输出到屏幕上Print将…...
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…...
Kaggle-Disaster Tweets-(二分类+NLP+模型融合)
Disaster Tweets 题意: 就是给出一个dataframe包含text这一列代表着文本,文本会有一些词,问对于每条记录中的text是真关于灾难的还是假关于灾难的。 比如我们说今天作业真多,这真是一场灾难。实际上这个灾难只是我们调侃而言的。…...
搭建一个网站需要选择什么配置的服务器?
一般要考虑网站规模、技术需求等因素来进行选择。 小型网站:个人博客、小型企业官网等日均量在 1000 以内的网站,一般推荐2 核 CPU、4GB 内存、50GB 硬盘,带宽 1 - 5M。如果是纯文字内容且图片较少的小型网站,初始阶段 1 核 CPU、…...
idea如何使用git
在 IntelliJ IDEA 中使用 Git 的详细步骤如下,分为配置、基础操作和高级功能,适合新手快速上手: 一、配置 Git 安装 Git 下载并安装 Git,安装时勾选“Add to PATH”。验证安装:终端输入 git --version 显示版本…...
webpack vite
1、webpack webpack打包工具(重点在于配置和使用,原理并不高优。只在开发环境应用,不在线上环境运行),压缩整合代码,让网页加载更快。 前端代码为什么要进行构建和打包? 体积更好&#x…...
.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防火墙大全 资源宝整理分享:https://www.htple.net PHP防火墙(作者:悠悠楠杉) 验证测试,链接后面加上?verify_cs1后可以自行测试 <?php //复制保存zzwaf.php$we…...
使用 Vitis Model Composer 生成 FPGA IP 核
本文将逐步介绍如何使用 Vitis Model Composer 生成 FPGA IP 核,从建模到部署。 在当今快节奏的世界里,技术正以前所未有的速度发展,FPGA 设计也不例外。高级工具层出不穷,加速着开发进程。传统上,FPGA 设计需要使用硬…...
Day08 【基于jieba分词实现词嵌入的文本多分类】
基于jieba分词的文本多分类 目标数据准备参数配置数据处理模型构建主程序测试与评估测试结果 目标 本文基于给定的词表,将输入的文本基于jieba分词分割为若干个词,然后将词基于词表进行初步编码,之后经过网络层,输出在已知类别标…...
BERT、T5、ViT 和 GPT-3 架构概述及代表性应用
BERT、T5、ViT 和 GPT-3 架构概述 1. BERT(Bidirectional Encoder Representations from Transformers) 架构特点 基于 Transformer 编码器:BERT 使用多层双向 Transformer 编码器,能够同时捕捉输入序列中每个词的左右上下文信息…...
倚光科技:以创新之光,雕琢全球领先光学设计公司
在光学技术飞速发展的当下,每一次突破都可能为众多领域带来变革性的影响。而倚光(深圳)科技有限公司,作为光学设计公司的一颗璀璨之星,正以其卓越的创新能力和深厚的技术底蕴,引领着光学设计行业的发展潮流…...
数据结构(六)——红黑树及模拟实现
目录 前言 红黑树的概念及性质 红黑树的效率 红黑树的结构 红黑树的插入 变色不旋转 单旋变色 双旋变色 插入代码如下所示: 红黑树的查找 红黑树的验证 红黑树代码如下所示: 小结 前言 在前面的文章我们介绍了AVL这一棵完全二叉搜索树&…...
【家政平台开发(48)】家政平台安全“攻防战”:渗透测试全解析
本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化,测试阶段多维度保障平台质量,…...
Python爬虫-爬取全球股市涨跌幅和涨跌额数据
前言 本文是该专栏的第52篇,后面会持续分享python爬虫干货知识,记得关注。 本文中,笔者将基于Python爬虫,实现批量采集全球股市行情(亚洲,美洲,欧非,其他等)的各股市“涨跌幅”以及“涨跌额”数据。 具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。…...
解决 Vue 中 input 输入框被赋值后,无法再修改和编辑的问题
目录 需求: 出现 BUG: Bug 代码复现 解决问题: 解决方法1: 解决方法2 关于 $set() 的补充: 需求: 前段时间,接到了一个需求:在选择框中选中某个下拉菜单时,对应的…...
【差分隐私相关概念】瑞丽差分隐私(RDP)-瑞丽散度约束了贝叶斯因子后验变化
分步解释和答案: 在Rnyi差分隐私(RDP)框架中,通过贝叶斯因子和Rnyi散度的关系可以推导出关于后验变化的概率保证。以下是关键步骤的详细解释: 1. 贝叶斯因子的定义与分解 设相邻数据集 D D D 和 D ′ D D′&#x…...
vue3 onMounted 使用方法和注意事项
基础用法 / 语法糖写法 <script> import { onMounted } from vue;// 选项式 API 写法 export default {setup() {onMounted(() > {console.log(组件已挂载);});} } </script><script setup> onMounted(() > {console.log(组件已挂载); }); </scrip…...
Dockerfile 文件常见命令及其作用
Dockerfile 文件包含一系列命令语句,用于定义 Docker 镜像的内容、配置和构建过程。以下是一些常见的命令及其作用: FROM:指定基础镜像,后续的操作都将基于该镜像进行。例如,FROM python:3.9-slim-buster 表示使用 Pyt…...
前端快速入门——JavaScript函数、DOM
1.JavaScript函数 函数是一段可重复使用的代码块,它接受输入(参数)、执行特定任务,并返回输出。 <scricpt>function add(a,b){return ab;}let cadd(5,10);console.log(c); </script>2.JavaScript事件 JavaScript绑定事件的方法࿱…...
shell 编程之循环语句
目录 一、for 循环语句 二、while 循环语句 三、until 循环语句 四、总结扩展 1. 循环对比 2. 调试技巧 3. 易混淆点解析 4. 进阶技巧 一、for 循环语句 1. 基础概念 含义: 用于 遍历一个已知的列表,逐个执行同一组命令 核心作用:…...
10【模块学习】LCD1602(二):6路温度显示+实时时钟
项目:6路温度显示实时时钟 1、6路温度显示①TempMenu.c文件的代码②TempMenu.h文件的代码③main.c文件的代码④Timer.c文件的代码⑤Delay.c文件的代码⑥Key.c文件的代码 2、实时时钟显示①BeiJingTime.c文件的代码②BeiJingTime.h文件的代码③main.c文件的代码如下④…...
