mysql查询选修课程的学生_[MySQL]查询学生选课的情况(一)
这是我工作遇到的问题,现在自己设计一个简化的类似场景,现实中这样的数据表设计可能有很多不合理的地方。
首先看表结构:
+--------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id | varchar(38) | NO | PRI | NULL | |
| name | varchar(255) | YES | | NULL | |
| course | varchar(300) | YES | | NULL | |
+--------+--------------+------+-----+---------+-------+
这里只是记录学生的ID,名字,还有选课的科目,科目有很多,在没有关联表的情况下,这么多科目只保存在一个字段中,用逗号隔开。
再看一些数据:
+--------------------------------------+--------+--------------------------------+
| id | name | course |
+--------------------------------------+--------+--------------------------------+
| 32268995-f33d-11e4-a31d-089e0140e076 | 张三 | Math,English,Chinese |
| 3d670ef2-f33d-11e4-a31d-089e0140e076 | 李四 | Math,English,Chinese,Algorithm |
| 475d51a6-f33d-11e4-a31d-089e0140e076 | 李五 | Math,English,Algorithm |
| 547fdea0-f33d-11e4-a31d-089e0140e076 | 王小明 | Math,English,Japanese |
| 656a247a-f33d-11e4-a31d-089e0140e076 | 曹达华 | Chesses |
+--------------------------------------+--------+--------------------------------+
那么如何查找到选择了Math课程的学生?
想想使用关联表的时候,张三, 李四, 李五, 王小明这四个人都一条选择了Math这门课的记录,还有其他不是Math的记录。此时要查找选择了Math课程的学生,一般使用IN语句就可以了:
select * from student_course where course IN ('Math');
如果要查找选择了Math或Algorithm课程的学生呢:
select * from student_course where course IN ('Math', 'Algorithm');
如此,回到原来的问题,如果我设计一个类似IN一样的函数,那么就可以解决这个问题了。
这个流程我们可以想象出来,是这样子的:
我们取张三的课程信息Math,English,Chinese,首先切割成Math, English,Chinese三个字段,然后分别与与查找条件做比较,类似'Math'.indexOf('Math');,'Math'.indexOf('English');…
只要找到一个就认为符合查找条件。
同样的,如果要查找选择了Math或Algorithm课程的学生,比较过程就变成了:
'Math,Algorithm'.indexOf('Math');,'Math,Algorithm'.indexOf('English');…
切割函数 getSplitTotalLength, getSplitString
CREATE DEFINER = `root`@`%` FUNCTION `getSplitTotalLength`(`f_string` varchar(500),`f_delimiter` varchar(5))
RETURNS int(11)
BEGIN
# 计算传入字符串能切分成多少段
return 1+(length(f_string) - length(replace(f_string,f_delimiter,'')));
RETURN 0;
END;
CREATE DEFINER = `root`@`%` FUNCTION `getSplitString`(`f_string` varchar(500),`f_delimiter` varchar(5),`f_order` int)
RETURNS varchar(500)
BEGIN
#拆分传入的字符串,分隔符,顺序,返回拆分所得的新字符串
declare result varchar(500) default '';
set result = reverse(substring_index(reverse(substring_index(f_string,f_delimiter,f_order)),f_delimiter,1));
RETURN result;
END;
类似IN的那个函数 isInSearch
CREATE DEFINER=`root`@`%` FUNCTION `isInSearch`(f_course VARCHAR(300), f_string VARCHAR(300)) RETURNS INT
BEGIN
DECLARE len INT DEFAULT 0;
DECLARE idx INT DEFAULT 0;
DECLARE item_code VARCHAR(300) DEFAULT '';
DECLARE item_index INT DEFAULT 0;
IF f_course IS NULL THEN
RETURN 0;
END IF;
SELECT getSplitTotalLength(f_course, ',') INTO len;
label: LOOP
SET idx = idx + 1;
IF idx > len THEN
LEAVE label;
END IF;
SELECT getSplitString(f_course , ',', idx) INTO item_code;
# f_string.indexOf(item_code) > -1 ?
SELECT LOCATE(item_code, f_string) INTO item_index;
IF item_index > 0 THEN
RETURN 1; # got one
END IF;
END LOOP label;
RETURN 0;
END;
这里说下locate函数,locate(item_code, f_string),如果item_code是f_string的子串,返回的结果大于0,是item_code在f_string的起始下标(从1开始算起),这个一般的indexOf函数有些不同。
mysql> select locate('Math','Math,Algorithm');
+---------------------------------+
| locate('Math','Math,Algorithm') |
+---------------------------------+
| 1 |
+---------------------------------+
mysql> select locate('Math','Chinese,Math,Algorithm');
+-----------------------------------------+
| locate('Math','Chinese,Math,Algorithm') |
+-----------------------------------------+
| 9 |
+-----------------------------------------+
mysql> select locate('Math','Chinese,Algorithm');
+------------------------------------+
| locate('Math','Chinese,Algorithm') |
+------------------------------------+
| 0 |
+------------------------------------+
可以看到isInSearch函数返回的是INT类似,因为MySQL的IN也是这样的机制。
mysql> select 'Math' in ('Math','Algorightm');
+---------------------------------+
| 'Math' in ('Math','Algorightm') |
+---------------------------------+
| 1 |
+---------------------------------+
mysql> select 'Math' in ('Chinese','Algorightm');
+------------------------------------+
| 'Math' in ('Chinese','Algorightm') |
+------------------------------------+
| 0 |
+------------------------------------+
如果存在返回1,不存在返回0。
在SELECT语句中使用自定义的函数
mysql> select * from student_course where isInSearch(course, 'Math');
+--------------------------------------+--------+--------------------------------+
| id | name | course |
+--------------------------------------+--------+--------------------------------+
| 32268995-f33d-11e4-a31d-089e0140e076 | 张三 | Math,English,Chinese |
| 3d670ef2-f33d-11e4-a31d-089e0140e076 | 李四 | Math,English,Chinese,Algorithm |
| 475d51a6-f33d-11e4-a31d-089e0140e076 | 李五 | Math,English,Algorithm |
| 547fdea0-f33d-11e4-a31d-089e0140e076 | 王小明 | Math,English,Japanese |
+--------------------------------------+--------+--------------------------------+
mysql> select * from student_course where isInSearch(course, 'Chinese,Japanese');
+--------------------------------------+--------+--------------------------------+
| id | name | course |
+--------------------------------------+--------+--------------------------------+
| 32268995-f33d-11e4-a31d-089e0140e076 | 张三 | Math,English,Chinese |
| 3d670ef2-f33d-11e4-a31d-089e0140e076 | 李四 | Math,English,Chinese,Algorithm |
| 547fdea0-f33d-11e4-a31d-089e0140e076 | 王小明 | Math,English,Japanese |
+--------------------------------------+--------+--------------------------------+
mysql查询选修课程的学生_[MySQL]查询学生选课的情况(一)相关推荐
- 查询选修课程2门以上且成绩都在80分以上的学生(MSSQL)
目录 题目要求 表结构 表样例 输出样例: 编译代码: 题目要求 查询选修课程数在2门以上(含2门)且所有选课成绩都在80分以上(含80分)的学生的姓名.专业名及总学分. 提示:MSSQLServer ...
- 10-10 查询选修课程超过2门且成绩都在80分以上的学生
本题目要求编写SQL语句,查询选修课程超过2门且成绩都在80分以上的学生的姓名.专业及总学分. 提示:请使用SELECT语句作答. 表结构: CREATE TABLE `major` (`mno` c ...
- 10-231 查询选修课程超过2门且成绩都在80分以上的学生
分数 10 全屏浏览题目 切换布局 作者 张庆 单位 集美大学 本题目要求编写SQL语句,查询选修课程超过2门且成绩都在80分以上的学生的姓名.专业及总学分. 表结构: 请在这里写定义表结构的SQL语 ...
- 查询选修“张三“老师所授课程的学生中,成绩最高的学生信息及其成绩
#每天进步一点点# MySQL 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩 1.以名字查出t_id SELECT t_id FROM teacher WHER ...
- 40、查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩(重要top)
-- 40.查询选修"张三"老师所授课程的学生中成绩最高的学生姓名及其成绩(重要top)SELECT st.s_name,sc.s_score FROM student as st ...
- SQL:检索没有选修某课程且选修课程数为两门的学生的姓名和平均成绩,并按平均成绩降序排列
一.库中有4个表 1.s表中有s#(学号).sn(学生姓名).age(学生年龄).dept(所在系) 2.c表中有c#(课程号).cn(课程名) 3.sc表中有s#(学号).c#(课程号).gr(成绩 ...
- 【sql: 练习题 28 ,29】查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况),查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数...
题目:查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况) 分析: 这个应该是student表 和 student_score表进行联合查询,因为存在学生没成绩,没选课的情况,所以要用lef ...
- mysql所有选修课程都及格_Day37:MySQL 数据库 ---(7)
一.Navicat Navicat是一个数据库管理软件.它是一个可视化的去连接MySQL的这么一个工具,本质上就是一个套接字客户端,只不过它是一个图形界面版的.它内部帮你封装了sql语句,给你暴露比较 ...
- mysql子查询一般分为几种_子查询一般分为几种
一.mysql子查询基本知识 子查询就是在原有的查询语句中,嵌入新的查询,来得到我们想要的结果集. 子查询一般分为:where型子查询.from型子查询和exists型子查询. 1.where型子查询 ...
- hadoop之MapReduce统计选修课程人数,不及格门数,选课人数
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.题目要求 二.数据解析 student.txt文件部分数据 三.需求分析及代码编写 总体的思路: 需求1:求DataB ...
最新文章
- 模型量化--TBN:Convolutional Neural Network with Ternary Inputs and Binary Weights
- 深入探讨Java中的异常与错误处理
- POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)
- 从Mysql某一表中随机读取n条数据的SQL查询语句
- 判断一个指针有没有free_Free Code Camp的每个人现在都有一个档案袋
- Leetcode——300. 最长上升子序列
- python中属性是什么意思啊_python中的“对象属性”和一般属性是什么?
- 代码中有的《飞秋》只是一个照面
- jQuery Mobile滚动事件
- mysql-sql命令
- 如何做好Web 安全测试
- Spring Boot 发送邮件
- Windows 8 开发者预览版下载及简体中文语言包下载
- 这三个博弈论新趋势,正深刻影响深度强化学习道翰天琼认知智能未来机器人接口API
- 用C语言实现万年历的代码及思路(详细教程)
- mui登录模板源码解
- 多个excel工作簿合并_无需VBA代码,1分钟合并多个工作簿至一个工作簿!
- Pubg九月十六日服务器维护,9月16日绝地求生更新时间公告 绝地求生9月16日更新维护...
- Ubutu 12.04LTS 安装搜狗拼音输入法+搜狗皮肤 步骤详解
- 【Linux】监控实时网速 查看实时网速