当前位置: 首页 > 后端技术 > PHP

Mysql入门第4课《数据查询》

时间:2023-03-29 17:25:54 PHP

原文在我的Github,欢迎订阅。前言在之前的几篇文章中,Mysql入门第一课《建表、改表、删表》Mysql入门第二课《数据类型》Mysql入门第三课《数据的增删改》之所以把数据查询单独作为一篇文章,是因为查询涉及到的知识点比较多,可以据说在增删改查中,查询的复杂度也是最高的。我以前学过一些非常简单的条件语句,比如WHEREid=2。单表查询很简单,但是多表查询在开发中比较常见,所以说说多表查询。预热当我们处理数据时,我们使用某个字段来检查与之相关的另一个信息。除了在数据库经常这样做,在前端也有类似的情况。我们先来看一个前端经常遇到的数据:{province:'江苏省',cities:['南京市','苏州市','无锡市']}上面是组合省市,只有embedded有两层,但是如果嵌套四五层,像这样:{province:'江苏省',children:[{name:'1市',children:[name:'江宁区',children:[name:'XX区']]},{name:'市2',children:[name:'AA区',children:[name:'BB区']]}]}这种数据将疯狂解析。一直在讲数据扁平化,我们扁平化一下://Provinceconstprovision=[{province:'江苏省',province_id:1001},{province:'浙江省',province_id:1002},...]//Cityconstcities=[{name:'南京市',province_id:1001},{name:'苏州市',province_id:1001},{name:'杭州市',province_id:1002},{name:'嘉兴City',province_id:1002},...]//查找江苏省所有城市constresult=cities.filter(i=>i.province_id===1001);数据扁平化的好处是,当我不需要找城市的时候,城市数据与我无关,我只需要关心省份,搜索性能更快(有时可以避免递归)。上面的例子引出了下面这句话:在数据库中,表通过一定的字段与表关联,这是关系数据库的核心。准备几张桌子。图中可以看到student表中有class_id,这样students和classes通过class_id关联起来。在开发过程中,我们可以使用它来查找类信息。查询我们用上表查询几个需求:查询成绩大于60分的学生,显示学生姓名和成绩查询马姓老师的人数查询没有学过该老师班级的学生姓名立即查询全部学生的姓名、修读的课程数量、成绩总和,都会一一分析。查询成绩大于60分的学生,显示学生姓名和成绩SELECTt1.student_name,t2.numberFROMstudentt1LEFTJOINscoret2ONt1.id=t2.student_idWHEREt2.number>60;先看结果:得到了正确的数据。分析语句:t1和t2分别是student和score的别名。细心的同学可以看到,我把上面的sql语句显示成三行,意思是:第一行:要查询的字段,很好理解第二行:其实它的结果是一个临时表!对应查询语句中的table_name!第三行:通俗易懂的WHERE条件语句,也就是说还是符合一般语法:SELECTcolumn_name,column_nameFROMtable_name[WHEREClause][LIMITN][OFFSETM]但是第一个第二个行创建一个临时表。这里涉及到JOINON语法,后面的章节会详细说明。下面是几篇相关文章:GraphicalSQL中的各种JOINs图解SQL的innerjoin,left/rightjoin,outerjoinDifferenceSQL多表查询:SQLJOIN连接查询查询马老师人数的各种用法总结SELECTCOUNT(id)ASteacher_numFROMteacherWHEREteacher_nameLIKE'马%';解析:COUNT(fieldName):COUNT函数用来统计某个字段的个数AS:别名LIKE:一般和%一起使用,模糊搜索,如果不加%就相当于精确搜索。%:表示任意字符,类似于正则表达式中的*,查询所有学生姓名、选课数、成绩总和。这个查询比较复杂。我们先上sql:SELECTt1.student_name,IFNULL(t2.course_num,0)AScourse_num,IFNULL(t2.sum_number,0)ASsum_numberFROMstudentt1LEFTJOIN(SELECTstudent_id,count(id)course_num,SUM(number)ASsum_numberFROMscoreGROUPBYstudent_id)t2ONt1.id=t2.student_id;接下来的结果:第一!不!想!恐慌!我们一点一点来分析。现在你脑子里应该先有一个通用的查询语句:SELECTcolumn_name,column_nameFROMtable_name[WHEREClause][LIMITN][OFFSETM]图中的查询语句翻译为:SELECTstudentname,numberofcoursesselected,sumofgradesFROMtable;那我们拆分一下上图中的查询:先看SELECTstudent_id,count(id)course_num,SUM(number)ASsum_numberFROMscoreGROUPBYstudent_id,我们分别执行这句话看结果:这条语句为我们生成了一张表,里面显示了学生id,选课数,总成绩,所以这张表代表核心,但是需求是给我们显示所有学生,所以必须依赖学生查询。如果上图中找到的结果命名为t2,就会变成:SELECTt1.student_name,IFNULL(t2.course_num,0)AScourse_num,IFNULL(t2.sum_number,0)ASsum_numberFROMstudentt1LEFTJOINt2ONt1.id=t2.student_id;删除一些“冗余”部分:SELECTt1.student_name,t2.course_num,t2.sum_numberFROMstudentt1LEFTJOINt2ONt1.id=t2.student_id;你明白吗?这里我介绍一下我没见过的语句:IFNULL(a,b):类似于普通的if语句,判断a是否为null,如果是则显示b。COUNT():计算读取数据中某个字段的个数,一般用于查询数据个数。SUM():求和,对读取的数据中的一个字段进行求和。GROUPBY:通过GROUPBY,可以设置使用哪些字段对读取的数据进行分组排序(默认升序)。需要注意的是,GROUPBY具有分组聚合功能。关于GROUPBY有几篇文章可以看:理解Groupby一张图让你详细了解GroupBy的分组聚合过程idINTUNSIGNEDPRIMARYKEYauto_increment,captionVARCHAR(30)COMMENT'classname');--学生表CREATETABLEstudent(idINTUNSIGNEDPRIMARYKEYauto_increment,student_nameCHAR(30)COMMENT'学生姓名',genderCHAR(30)DEFAULTNULLCOMMENT'学生性别',class_idINTDEFAULTNULLCOMMENT'班级id');--teachertableCREATETABLEteacher(idINTUNSIGNEDPRIMARYKEYauto_increment,teacher_nameCHAR(30)COMMENT'teachername');--班级表CREATETABLEcourse(idINTUNSIGNEDPRIMARYKEYauto_increment,course_nameCHAR(30)COMMENT'coursename',teacher_idINTDEFAULTNULLCOMMENT'teacherid');--scoretableCREATETABLEscore(idINTUNSIGNEDPRIMARYKEYauto_incrementINT,numberDEFAULTNULLCOMMENT'score',student_idINTDEFAULTNULLCOMMENT'学号',course_idINT默认NULL评论“课程编号”);总结一下,这篇文章主要是理解查询,但这只是练习,实际开发中比较难的是查询很多,没事的时候需要多练习。今天工作比较忙,所以文章可能有点粗糙。如果我错了,请纠正我。