chatGPT非常重要的能力居然不行,就让这个工具来拯救,让你SQL操作无忧

news2024/12/24 10:34:47

引言

各位好,相信看见这篇文章的朋友,应该也去体验过了chatGPT了吧~,确实chatGPT拉近了我们与未来科技的距离,所有别人火也是非常有道理的,为其点赞。

本文主要是关注chatGPT的SQL能力;因为本人从事IT教育行业,有大量的学生,在这些学生学习过程中有一个共同的技能学起来非常的难或者痛苦,其就是SQL操作能力。所有在本人心中一直有一个项目就是用AI来实现学生们的SQL训练,而且一直在着手行动。chatGPT出来的第一时间,我其实就特别关注,也去试了试相关的SQL功能,但是非常遗憾,chatGPT无法提供相关的功能。

chatGPT官网界面

鉴于此,chatGPT不支持,那么本人也是还有机会的,所有加班赶了3天,做出了一套能「自动识别数据库表关系,自动依据表数据生成SQL练习题的工具」,如下:

  • 自动识别当前数据库中的表、表中的数据,生成对用SQL练习题(每个数据库表数量、数据数量不同,生成的练习数量也不同)

  • SQL练习题自动生成答案

  • SQL练习题可直接运行和比对答案

Tinkle 软件生成SQL练习题演示

为什么chatGPT不支持SQL呢?

其实这个原因非常简单,SQL练习题,需要数据库表结构还有数据,光有数据库表没有数据的SQL练习就是扯犊子,而chatGPT实现表的结构数据收集非常容易,但是它做不到数据的收集,因此这个课题它实现不了。

为什么您能实现呢?

本人在IT行业十几年的经验,深刻体会数据的价值,因此在去年就开始着手实现一系列的软件工具(主要是数据库、redis等客服端工具,如上图),用户使用工具的同时,其实就是赋予了工具读取到这些数据的能力,那么关键的数据问题就解决了;那么在结合一些表结构的分析方法,就可以做一些表规范、SQL练习等相关的功能,提升用户对工具的使用体验。接下来本人也聊聊我是想这些智能化一点的功能思路。

智能SQL练习题实现功能思路★★★

如下图,整体思路核心还是基于SQL模板来实现,但是在整个实现过程中有以下几个难点,指的关注:

  • 如何准确的识别表结构的ER关系? 这个不能基于物理外键关系来实现,因为大多表都没有物理外键;

  • 如何让SQL模板引擎生成的题有数据?

  • 如何对比生成的答案和用户输入的答案?

如何识别数据库的逻辑ER结构?★★★

在工作中一般是禁止使用物理外键来约束表与表之间的关系的,那么没这种关系怎么样实现逻辑外键的识别和ER结构的关系呢?本人采取的思路是,使用字段名称的自动匹配,这个想法来源于工作经验的总结:大部分程序员设计一张user表,id字段是主键;设置一张用户地址信息表是其中会设计一个user_id字段来逻辑关联用户表;基于这样一种定于,那么就可以基于名称来实现逻辑关系,本人以下ER关系图就是基于此方式来生成的:

如何基于SQL模板技术生成对应试题?★★★

模板技术就是提供好模板,动态的填充各类数据,这个大家应该比较场景,但是指的注意的是:

  • 生成的模板包括:

    • 题目标题

    • 题目提示

    • 题目答案

    • 题目输出

  • 生成题目是还需要动态检查数据是否满足,如果不满足则跳过,满足则生成试题

勇哥给出一段模板参考代码:

package com.madou.dbtool.relationship.panel.exercise.question;

import com.madou.common.annotation.HideClass;
import com.madou.dbtool.constans.Constans;
import com.madou.dbtool.relationship.common.BasePanelParm;
import com.madou.dbtool.relationship.panel.exercise.BaseExercise;
import com.madou.dbtool.relationship.panel.exercise.pojo.OutDegree;
import com.madou.dbtool.relationship.panel.exercise.pojo.QuestionTable;
import com.madou.dbtool.relationship.panel.exercise.pojo.ReferenceAnswer;
import com.madou.dbtool.relationship.panel.exercise.pojo.SqlQuestion;
import com.madou.dbtool.relationship.pojo.FieldInfo;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 有多对多的3张表,生成
 */
@HideClass
public class Case2Question extends BaseExercise {

    @Override
    public String name() {
        return "1对多-统计练习题-CASE百分位";
    }

    @Override
    public List<String> lables() {
        return Arrays.asList("case when then","1:N","left join","sum","count","min","max");
    }

    @Override
    public String category() {
        return "1对多";
    }

    @Override
    public int needTableCount() {
        return 1;
    }

    // 生成问题
    @Override
    public SqlQuestion generatorQuestion(BasePanelParm basePanelParm, Map<String,List<Map<String, Object>>> datas, QuestionTable questionTable) {
        List<OutDegree> outs = questionTable.getOut();
        int size = questionTable.getOut().size();
        if(size>1){
            int index1 = Constans.RANDOM.nextInt(outs.size());
            int index2 = Constans.RANDOM.nextInt(outs.size());
            while (index2==index1){
                index2 = Constans.RANDOM.nextInt(outs.size());
            }
            OutDegree mainTable = outs.get(index1);// 结果信息表
            OutDegree resuTable = outs.get(index2);// 结果信息表
            try {
                    FieldInfo fieldInfo = chooseNumberField(questionTable.getFields());
                    if (fieldInfo == null) {
                        return null;
                    }
                    int num = 100;
                    try {
                        // 判断数据是否满足生成实体的条件,如果满足则生成,不满足则跳过
                        String sql = String.format("select max(%s) as count from %s", fieldInfo.getName(), questionTable.getTableInfo().getName());
                        List<Map<String, Object>> queryResult = getDataLimit(basePanelParm, datas, sql, 1);
                        if (queryResult != null && queryResult.size() > 0) {
                            Object count = queryResult.get(0).get("count");
                            if (count != null) {
                                num = Double.valueOf("" + queryResult.get(0).get("count")).intValue();
                            } else {
                                return null;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    int nums[] = new int[]{0,num/4,num/2,num*3/4,num};
                    if (fieldInfo != null) {
                        String resuDesc = getTableDesc(resuTable.getQuestionTable().getTableInfo());
                        SqlQuestion sqlQuestion = new SqlQuestion();
                        sqlQuestion.setName(getQuestionTitle(fieldInfo, nums, resuDesc));
                        sqlQuestion.setThinking(getThinking());
                        sqlQuestion.addReferenceAnswer(getAnswer(questionTable,fieldInfo,resuTable,nums));
                        sqlQuestion.setOutColumn(getOutColumn(resuTable,nums));
                        return sqlQuestion;
                    }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 生成结果要输出的字段说明
     * @param resuTable
     * @return
     */
    public Map<String,String> getOutColumn(OutDegree resuTable,int[] nums){
        Map<String,String> outColumn = new HashMap<>();
        outColumn.put("section1","[0,"+nums[1]+"]段");
        outColumn.put("section2","["+nums[1]+","+nums[2]+"]段");
        outColumn.put("section3","["+nums[2]+","+nums[3]+"]段");
        outColumn.put("section4","["+nums[3]+","+nums[4]+"]段");
        for (FieldInfo field : resuTable.getQuestionTable().getFields()) {
            outColumn.put(field.getName(),getFieldDesc(field));
        }
        return outColumn;
    }

    /**
     * 生成参考答案
     * @param questionTable
     * @param fieldInfo
     * @return
     */
    public ReferenceAnswer getAnswer(QuestionTable questionTable, FieldInfo fieldInfo ,OutDegree resuTable,int[] nums){
        String sql = "select c.*, b.section1, b.section2, b.section3, b.section4\n" +
                "from %s c\n" +
                "    left join (\n" +
                "        select %s\n" +
                "            , sum(case \n" +
                "                when %s >= 0\n" +
                "                    and %3$s < %s\n" +
                "                then 1\n" +
                "                else 0\n" +
                "            end) as section1\n" +
                "            , sum(case \n" +
                "                when %3$s >= %4$s\n" +
                "                    and %3$s < %s\n" +
                "                then 1\n" +
                "                else 0\n" +
                "            end) as section2\n" +
                "            , sum(case \n" +
                "                when %3$s >= %5$s\n" +
                "                    and %3$s < %s\n" +
                "                then 1\n" +
                "                else 0\n" +
                "            end) as section3\n" +
                "            , sum(case \n" +
                "                when %3$s >= %6$s\n" +
                "                    and %3$s <= %s\n" +
                "                then 1\n" +
                "                else 0\n" +
                "            end) as section4\n" +
                "        from %s\n" +
                "        group by %2$s\n" +
                "    ) b\n" +
                "    on c.id = b.%2$s";
        return new ReferenceAnswer(String.format(sql,
                resuTable.getQuestionTable().getTableInfo().getName(),
                resuTable.getFieldInfo().getName(),
                fieldInfo.getName(),
                nums[1],
                nums[2],
                nums[3],
                nums[4],
                questionTable.getTableInfo().getName()
         ));
    }

    /**
     * 生成问题的标题
     * @param resuDesc
     * @return
     */
    public String getQuestionTitle(FieldInfo fieldInfo, int[] nums,String resuDesc){
        return String.format("统计每个%s的各%s段人数[0,%s]、[%3$s,%s]、[%4$s,%s]、[%5$s,%s], 分别取别名为section1、section2、section3、section4.并显示%1$s基本信息",
                resuDesc,
                getFieldDesc(fieldInfo),
                nums[1],
                nums[2],
                nums[3],
                nums[4]);
    }

    /**
     * 生成问题思路
     * @return
     */
    public String getThinking(){
        return String.format("group by 以后的查询结果无法使用别名,所以不要想着先单表 group by 计算出结果再从第二张表里添上课程信息,而应该先将两张表 join 在一起得到所有想要的属性再对这张总表进行统计计算.");
    }

}

如何对比生成的答案和用户输入的答案?★★★

首先大家想到的是直接对比输入和答案的SQL语法,但是勇哥没有按这个思路实现,因为同一个需求SQL有多种写发;因此对比结果最好采取数据结果集对比;把用户输入的SQL的结果与标准答案SQL的结果集逐行对比,用户输入的SQL的结果完成匹配则答对。这种方式有点耗性能,但是效果最直观,也是可取的;性能问题可以现在一下两个结果集最大不错过20行数据。

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

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

相关文章

用友T+数据备份与恢复方法汇总

一、正常数据备份与恢复 适合于用友T能正常登陆、正常备份的情况。 1、数据备份 以系统管理员admin登陆系统管理&#xff0c;点击“账套维护”&#xff0c;选择好需要备份的账套&#xff0c;点击“备份”&#xff0c;同时设置好备份路径&#xff0c;保存备份文件即可&#xf…

(附源码)Springboot服装网购网站 毕业设计 010234

Springboot服装网购网站 摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管…

Day825.死锁问题 -Java 并发编程实战

死锁问题 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于死锁问题。 用 Account.class 作为互斥锁&#xff0c;来解决银行业务里面的转账问题&#xff0c;虽然这个方案不存在并发问题&#xff0c;但是所有账户的转账操作都是串行的&#xff0c;例如账户 A 转账户 B…

【华为上机真题 2022】完全二叉树非叶子节点后序遍历

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

不知道哪个视频软件可以一键成片?建议收藏这些软件

随着短视频平台的不断发展&#xff0c;越来越多的小伙伴加入进了短视频剪辑的行列当中。现在市面上的视频剪辑软件很多&#xff0c;但是对于新手小白来说&#xff0c;能够快速上手使用的视频编辑软件才是重要的。那你们知道一键成片视频软件哪个好吗&#xff1f;有想要制作短视…

2、基于XML的依赖注入详细配置

一、依赖注入详细配置 1、通过P名称空间为Bean注入值 1、简化setter方式注入的配置&#xff0c;可以不使用<property />子标签来为属性设置值&#xff0c;直接在<bean />标签中设置各依赖项的值。 2、注入值类型说明&#xff1a; 对于String、基本类型及其包装类使…

visio绘图小技巧

1.如何在图框的任意位置添加点&#xff1f; 先选中x点指令&#xff0c;再按住ctrl键&#xff0c;即可在任意位置画点 2.如何画出锯齿形线段&#xff1f; visio里面好像没有现成的锯齿形线段&#xff0c;所以可以利用直线反复折画&#xff0c;但是这里有个小技巧&#xff0c;就…

[附源码]JAVA毕业设计小王防疫副食品配送商城(系统+LW)

[附源码]JAVA毕业设计小王防疫副食品配送商城&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项…

获取网易云音乐开放接口api的推荐歌单

网易云音乐开放api接口 网址&#xff1a;https://binaryify.github.io/NeteaseCloudMusicApi/#/?idneteasecloudmusicapi 项目地址&#xff1a;https://github.com/Binaryify/NeteaseCloudMusicApi 下载下来之后&#xff0c;安装依赖&#xff1a;npm install 启动服务&#xf…

决策树(decision tree)

决策树构建&#xff1a;特征选择、决策树的生成和决策树的修剪。 特征选择 特征选择在于选取对训练数据具有分类能力的特征。这样可以提高决策树学习的效率&#xff0c;如果利用一个特征进行分类的结果与随机分类的结果没有很大差别&#xff0c;则称这个特征是没有分类能力的…

Lifeform——站在3D虚拟数字身份与元宇宙结合的风口之上

Web3和元宇宙是公认的下一个风口&#xff0c;吸引了大量用户的关注和参与。从《我的世界》中的场景编辑器&#xff0c;到DecentreLand&#xff0c;以及Sandbox中玩家对自己虚拟地块的装饰。人们在虚拟世界中举办各种活动&#xff0c;比如演唱会、节日庆祝或者比赛、游戏甚至婚礼…

PrizmDoc Viewer添加了新的Excel渲染选项

PrizmDoc Viewer添加了新的Excel渲染选项 添加了新的Microsoft Excel渲染选项。PrizmDoc Viewer现在提供了在MSO渲染模式下查看Excel文档时自动调整单元格宽度和/或高度的选项。 PrizmDoc Viewer Microsoft Office转换附加选项现在与运行在Microsoft Windows Server 2019/2022上…

谷粒商城8:分布式锁使用和springcache的整合

1.分布式锁redisson使用 ①分布式锁简介 ②分布式锁学习过程 ③最终分析 加入锁为原子操作&#xff1a;设置过期时间设置锁 删除锁为原子操作&#xff1a;业务流程删除锁 将锁的过期时间调长 ④Redisson的使用 引入依赖程序化配置使用 创建redisson客户端 Redisson.create(…

6.论文学习Modality-aware Mutual Learning for Multi-modal Medical Image Segmentation

目录一.摘要1.背景解决方法1.如何有效整合来自多模态医学图像的信息2.如何处理常见模式缺失的情况2.解决1.ML2.MA3.结论二.方法2.1模态特定模型Modality-specific Model2.2 Modality-Aware Module2.3互学策略Mutual Learning Strategy三.实验与结果3.1数据集和评估指标3.2运行细…

杨校老师课堂之Spring Boot框架面试题【开发工程师面试前必看】

1. 什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 开源组织下的子项目&#xff0c;是 Spring 组件一站式解决方案&#xff0c;主要是简化了使用Spring 的难度&#xff0c;简省了繁重的配置&#xff0c;提供了各种启动器&#xff0c;使开发者能快速上手。 2. 为什么要用…

c#入门-别名引用

别名引用 如果你引用的命名空间中出现了同名的类&#xff0c;那么会无法判断你使用的类型。 当然&#xff0c;你可以使用完全限定名。 或者&#xff0c;你可以为其中一个类型指代别名。 使用引用命名空间语句&#xff0c;为一个标识符赋值一个类型。 可以使用这个标识符代替…

基于java+springmvc+mybatis+jsp+mysql的通信簿管理系统

项目介绍 前端页面&#xff1a; 功能&#xff1a;首页、日志信息、心情日志、相册信息、个人中心、后台管理 管理员后台页面&#xff1a; 功能&#xff1a;主页、个人中心、用户管理、日志信息管理、日志类别管理、心情日志管理、相册信息管理、系统管理 开发环境 开发语言&…

C#【必备技能篇】Marshal是什么?怎么用?

文章目录学习来源&#xff1a;MSDN官方文档一、Marshal是什么&#xff1f;1、英文释义&#xff1a;2、在MSDN中的定义&#xff1a;3、通俗理解&#xff1a;二、Marshal怎么用&#xff1f;【主要以一些实例来了解】1、Marshal下的方法_部分截图【C#源码】&#xff1a;2、一些示例…

自定义RBAC(3)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; RBAC类型的权限&#xff0c;本质上是一种对资源访问路径的控制&#xff0c;且具有典型的树型层次结构。而树型结构&#xff0c;天然地就有父结点和子结点的关系以…

【HarmonyOS】ArkTS Native开发——使用 system函数创建文件

ArkTS是HamronyOS优选的主力语言&#xff0c;但官方文档指南中对于Native应用开发并没有详细的描述&#xff0c;只有一篇Codelab可以学习&#xff08;简易Native C 示例&#xff08;ArkTS&#xff09; (huawei.com)&#xff09;&#xff0c;本文将在Native应用中使用C/C的syste…