这是我工作遇到的问题,现在自己设计一个简化的类似场景,现实中这样的数据表设计可能有很多不合理的地方。

首先看表结构:

+--------+--------------+------+-----+---------+-------+

| 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]查询学生选课的情况(一)相关推荐

  1. 查询选修课程2门以上且成绩都在80分以上的学生(MSSQL)

    目录 题目要求 表结构 表样例 输出样例: 编译代码: 题目要求 查询选修课程数在2门以上(含2门)且所有选课成绩都在80分以上(含80分)的学生的姓名.专业名及总学分. 提示:MSSQLServer ...

  2. 10-10 查询选修课程超过2门且成绩都在80分以上的学生

    本题目要求编写SQL语句,查询选修课程超过2门且成绩都在80分以上的学生的姓名.专业及总学分. 提示:请使用SELECT语句作答. 表结构: CREATE TABLE `major` (`mno` c ...

  3. 10-231 查询选修课程超过2门且成绩都在80分以上的学生

    分数 10 全屏浏览题目 切换布局 作者 张庆 单位 集美大学 本题目要求编写SQL语句,查询选修课程超过2门且成绩都在80分以上的学生的姓名.专业及总学分. 表结构: 请在这里写定义表结构的SQL语 ...

  4. 查询选修“张三“老师所授课程的学生中,成绩最高的学生信息及其成绩

    #每天进步一点点# MySQL 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩 1.以名字查出t_id SELECT t_id FROM teacher WHER ...

  5. 40、查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩(重要top)

    -- 40.查询选修"张三"老师所授课程的学生中成绩最高的学生姓名及其成绩(重要top)SELECT st.s_name,sc.s_score FROM student as st ...

  6. SQL:检索没有选修某课程且选修课程数为两门的学生的姓名和平均成绩,并按平均成绩降序排列

    一.库中有4个表 1.s表中有s#(学号).sn(学生姓名).age(学生年龄).dept(所在系) 2.c表中有c#(课程号).cn(课程名) 3.sc表中有s#(学号).c#(课程号).gr(成绩 ...

  7. 【sql: 练习题 28 ,29】查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况),查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数...

    题目:查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况) 分析: 这个应该是student表 和  student_score表进行联合查询,因为存在学生没成绩,没选课的情况,所以要用lef ...

  8. mysql所有选修课程都及格_Day37:MySQL 数据库 ---(7)

    一.Navicat Navicat是一个数据库管理软件.它是一个可视化的去连接MySQL的这么一个工具,本质上就是一个套接字客户端,只不过它是一个图形界面版的.它内部帮你封装了sql语句,给你暴露比较 ...

  9. mysql子查询一般分为几种_子查询一般分为几种

    一.mysql子查询基本知识 子查询就是在原有的查询语句中,嵌入新的查询,来得到我们想要的结果集. 子查询一般分为:where型子查询.from型子查询和exists型子查询. 1.where型子查询 ...

  10. hadoop之MapReduce统计选修课程人数,不及格门数,选课人数

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.题目要求 二.数据解析 student.txt文件部分数据 三.需求分析及代码编写 总体的思路: 需求1:求DataB ...

最新文章

  1. 模型量化--TBN:Convolutional Neural Network with Ternary Inputs and Binary Weights
  2. 深入探讨Java中的异常与错误处理
  3. POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)
  4. 从Mysql某一表中随机读取n条数据的SQL查询语句
  5. 判断一个指针有没有free_Free Code Camp的每个人现在都有一个档案袋
  6. Leetcode——300. 最长上升子序列
  7. python中属性是什么意思啊_python中的“对象属性”和一般属性是什么?
  8. 代码中有的《飞秋》只是一个照面
  9. jQuery Mobile滚动事件
  10. mysql-sql命令
  11. 如何做好Web 安全测试
  12. Spring Boot 发送邮件
  13. Windows 8 开发者预览版下载及简体中文语言包下载
  14. 这三个博弈论新趋势,正深刻影响深度强化学习道翰天琼认知智能未来机器人接口API
  15. 用C语言实现万年历的代码及思路(详细教程)
  16. mui登录模板源码解
  17. 多个excel工作簿合并_无需VBA代码,1分钟合并多个工作簿至一个工作簿!
  18. Pubg九月十六日服务器维护,9月16日绝地求生更新时间公告 绝地求生9月16日更新维护...
  19. Ubutu 12.04LTS 安装搜狗拼音输入法+搜狗皮肤 步骤详解
  20. 【Linux】监控实时网速 查看实时网速

热门文章

  1. 深度实践嵌入式linux系,深度实践嵌入式Linux系统移植 完整pdf_操作系统教程_源雷技术空间...
  2. 某游戏彩票外企Java面试题
  3. 永中软件自己越描越黑
  4. 花了一晚上时间,终于把Python的基本用法归纳好了
  5. IDEA常用设置和插件推荐
  6. 用Python调用迅雷实现后台批量下载
  7. Android开发指南中文版
  8. 未来十年,互联网将如何颠覆17个传统行业
  9. 《JavaEE开发技术》课程考试试题(A卷)
  10. 废水中COD高怎么办