自动依据你的数据库生成SQL练习题及答案,宝藏软件鉴赏

news2025/2/21 23:34:12

原创软件不易,方面多点赞、收藏、加关注鼓励!后续领更多好用功能!

引言

各位好,相信看见这篇文章的朋友,应该也去体验过了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/76878.html

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

相关文章

电脑技巧:Microsoft Edge浏览器技巧介绍

目录 1、导入浏览器数据 2、Edge边栏 3、实用的扩展功能 4、创建集锦列表 4.1 集锦的作用 4.2 使用方法 5、查找优惠券 6、Edge效率省电模式 Microsoft Edge是Windows10操作系统预装的一款非常棒的浏览器和之前的IE不同&#xff0c;采用了谷歌浏览器内核&#xff0c;相…

项目的成功标准如何衡量?【一杯咖啡谈项目】

每个项目经理都想自己的项目能够成功&#xff0c;但是&#xff0c;什么才叫项目的成功&#xff0c;成功的定义是什么&#xff1f;项目成功标准是什么呢&#xff1f; 很多看似失败的项目其实是成功的&#xff0c;很多看似成功的项目其实是失败的。研究项目成功的标准&#xff0…

Chrome 扩展插件:如何开始一个插件的开发

欢迎点击查看个人站首发原文&#xff0c;访问个人站获取更多插件编程知识。 Chrome扩展插件基础是基于前端htmljs开发&#xff0c;然后通过官方提供的项目结构进行开发&#xff0c;需要注意的是&#xff0c;目前Chrome已经支持Manifest V3&#xff0c;FireFox仅仅支持Manifest …

【大数据入门核心技术-Impala】(一)Impala简介

目录 一、Impala介绍 二、Impala优势 三、Impala主要功能 一、Impala介绍 Impala是Cloudera公司主导开发的新型查询系统&#xff0c;它提供SQL语义&#xff0c;能查询存储在Hadoop的HDFS和HBase中的PB级大数据。已有的Hive系统虽然也提供了SQL语义&#xff0c;但由于Hive底层…

代码详细教程+文档+PPT+源码等]SSM框架美妆商城全套|电商购物计算机专业毕业论文java毕业设计网站

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 计算机毕业设计java毕设之SSM美妆商城项目源码_哔哩哔哩_bilibili项目资料网址: http://itzygogogo.com软件下载地址:http://itzygogogo.com/itsz…

[附源码]Python计算机毕业设计SSM基于框架的在线健康系统设计与实现(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

DRF和vue跨域问题的解决

跨域不一定都会有跨域问题&#xff1a; 因为跨域问题是浏览器对于ajax请求的一种安全限制&#xff1a;一个页面发起的ajax请求&#xff0c;只能是与当前页域名相同的路径&#xff0c;这能有效的阻止跨站攻击。因此&#xff0c;跨域问题 是针对ajax的一种限制。 但是这却给我们…

Birdboot第二天 Request Response

目录 V4 HttpServletRequest保存请求内容 1.此类专门处理请求 把获取请求的readline()和拆分代码移动过来 2.ClientHandler客户端处理器实例化HttpServletRequest 3. 拆分的信息从局部变量 变成属性 4.建方法 解析请求行 消息头 消息正文 V5 发送响应 1.在客户端处理器 …

BI智慧仓储,带你体验数字化仓储物流管理

1、行业背景 智能仓储物流是以信息交互为主线&#xff0c;使用条形码、射频识别、传感器、全球定位系统等先 进的物联网技术&#xff0c;集成自动化、信息化、人工智能技术&#xff0c;通过信息集成、物流全过程优化 以及资源优化&#xff0c;使物品运输、仓储、配送、包装、装…

【小f的刷题笔记】(JS)链表 - 合并 k 个有序链表 LeetCode23 - 顺序合并暴力三种方法

【链表】 合并 k 个有序链表&#xff1a; &#x1f31f; 想办法从一堆节点中找到最小的那个节点 看了很多题解&#xff0c;主要是以下四种方法&#xff08;优先队列我还没有写出来&#xff0c;先遗留着&#xff09;&#xff1a; ✔ 顺序合并 ✔ 分治合并&#xff08;归并&a…

【单片机】矩阵键盘/定时器

目录 一、矩阵键盘 1、矩阵按键原理 1.1工作方式 1.2工作原理 1.3单片机IO口 2、矩阵键盘数字显示代码 3、矩阵键盘密码锁 二、定时器&#xff08;工作模式1&#xff09; 1、定时器的原理 2、寄存器 2.1模式选择寄存器TMOD&#xff08;不可位寻址&#xff09; 2.2…

CentOS 搭建 WordPress 站点

博客链接:https://www.aiiyx.cn 内容纲要 1. 版本相关2. 主要内容3. 安装并配置 PHP4. 安装并配置 WordPress5. 配置 Nginx6. 配置 MySQL7. 初始化 WordPress 1. 版本相关 WordPress 版本 5.9.3PHP 版本 8.1MySQL 版本 5.7Nginx 版本 1.18 2. 主要内容 由于我的 CentOS 服务…

ChatGPT:将你的微信变成智能聊天机器人!

天天用微信的你有没有做个这样一种设想&#xff1a;让最先进的人工智能算法帮你聊天! 这机器人可以回答各种问题&#xff0c;上知天文下知地理&#xff0c;甚至还能写代码。无论是哄女朋友&#xff0c;应付老婆&#xff0c;或者勾搭陌生小姐姐&#xff0c;都能做到24小时在线&…

一文带领大家了解什么是泛型

对于泛型&#xff01;其实大家了解不是很多&#xff0c;在各大高校的学习中&#xff0c;如果你不去深入的了解泛型&#xff0c;老师只是会一水儿过&#xff0c;并不会单独去带领大家了解&#xff01;&#xff01;那么&#xff0c;笔者结合自身的学习泛型的想法&#xff0c;结合…

2022年双十二拼多多百亿补贴有活动吗?如何领红包?

2022年双十二拼多多百亿补贴有活动吗?如何领红包? 拼多多的活动大家都很清楚&#xff0c;平常没有活动的时候&#xff0c;价格也是比较实惠的&#xff0c;除了拼团购物之外&#xff0c;拼多多还有百亿补贴&#xff0c;所以商品比其他平台都要便宜&#xff0c;双十二拼多多百亿…

物理数据库服务器扫描hba卡识别共享磁盘命令

1、问题背景 默认情况&#xff0c;在扩容完1套物理rac共享存储后&#xff0c;rac主机是不能识别共享存储的。那么该怎么办呢&#xff1f; 2、解决办法 例如&#xff0c;在扩容完1套物理rac共享存储后&#xff0c;如果rac主机不能识别共享存储的话(一般需要执行命令后&#x…

Jboss弱口令Getshell

文章目录漏洞简介影响版本环境搭建漏洞复现漏洞简介 JBoss Administration Console存在默认账号密码admin/vulhub&#xff0c;如果Administration Console可以登录&#xff0c;就可以在后台部署war包getshell 影响版本 Jboss4.x及其之前的版本 console 管理路径为/jmx-consol…

day16【代码随想录】反转字符串、反转字符串中的元音字母、反转字符串||、反转字符串中的单词|||、替换空格、翻转字符串中的单词、左旋转字符串

文章目录一、反转字符串&#xff08;力扣344&#xff09;二、反转字符串中的元音字母&#xff08;力扣345&#xff09;三、反转字符串 II&#xff08;力扣541&#xff09;四、反转字符串中的单词 III&#xff08;力扣557&#xff09;五、替换空格&#xff08;剑指 Offer 05&…

Kubernetes ~ k8s 从入门到入坑。

Kubernetes ~ k8s 从入门到入坑。 文章目录Kubernetes ~ k8s 从入门到入坑。1. Kubernetes 介绍。1.1 应用部署方式演变。1.2 kubernetes 简介。1.3 kubernetes 组件。1.4 kubernetes 概念。2. kubernetes 集群环境搭建。2.1 前置知识点。2.2 kubeadm 部署方式介绍。2.3 安装要…

人工智能前沿——玩转OpenAI聊天机器人ChatGPT(免费中文版)

目录 2022 地表最强AI聊天机器人ChatGPT诞生&#xff01;&#xff01;&#xff01; 一、前言 &#x1f384;&#x1f388; ChatGPT是OpenAI开发的一个大型预训练语言模型。它是GPT-3模型的变体&#xff0c;GPT-3经过训练&#xff0c;可以在对话中生成类似人类的文本响应。Cha…