MySQL数据库:基本查询 文章目录mysql基本查询通关手册从crud到分组统计新手避坑全攻略一、先搞懂表是什么二、create先建一张表2.1 最简单的建表例子2.2 大白话解释每个词2.3 新手建表避坑三、insert往表里加数据3.1 单行全列插入3.2 指定列插入3.3 一次插多行3.4 插入避坑四、select从表里查数据4.1 查所有列4.2 只查指定列4.3 给列起个别名4.4 按条件筛选where常用比较运算符逻辑运算符模糊查询like⚠️ 超级大坑null不能用判断4.5 新手高频报错where里用别名4.6 排序order by4.7 分页limit五、update修改表里的数据5.1 修改指定行5.2 ❗️ 致命提醒千万别忘写where5.3 更新避坑六、delete删除表里的数据6.1 删除指定行6.2 ❗️ 致命提醒千万别忘写where6.3 清空全表的另一种方式truncate6.4 delete和truncate的区别七、分组统计聚合函数 group by7.1 五个常用聚合函数7.2 group by到底在干嘛7.3 基本用法分组 聚合例1统计每个班有多少人例2统计每个班的数学成绩情况例3多字段分组7.4 新手灵魂拷问分完组原始行还在吗7.5 想要明细 分组统计用窗口函数7.6 having分组后筛选7.7 where和having的区别八、必懂底层逻辑sql执行顺序8.1 真实执行顺序8.2 大白话类比做菜的顺序8.3 懂了执行顺序有啥用九、新手避坑终极清单十、最后ai时代怎么学mysql基本查询通关手册从crud到分组统计新手避坑全攻略很多刚接触mysql的同学一听到“数据库”“sql”就觉得很高深。其实完全不用怕你就把数据库表当成一张班级花名册所有操作全是日常逻辑画一张新的空白表格 建表create往表格里填新同学信息 插入数据insert从表格里找人、找成绩 查询数据select修改表格里写错的信息 更新数据update把同学从表格里划掉 删除数据delete这四个操作合起来就是数据库里最基础的crud。今天咱们完全从零起步用大白话可直接运行的例子把mysql基本语法讲明白新手也能看完就上手敲。一、先搞懂表是什么表就是一张有行有列的表格和excel里的表一模一样列字段表格的表头比如姓名、学号、语文成绩规定了这一列能填什么类型的数据行记录表格里的每一行数据比如一个同学的所有信息就是一行记录后面所有操作我们都用「学生成绩表」当例子跟着敲一遍就能学会。二、create先建一张表说白了就是画一张空白表格先定好有几列、每列叫什么、能填啥。2.1 最简单的建表例子我们先建一张学生表createtablestudents(idintunsignedprimarykeyauto_incrementcomment编号,snintnotnulluniquecomment学号,namevarchar(20)notnullcomment姓名,qqvarchar(20)commentqq号);2.2 大白话解释每个词不用死记知道大概意思就行关键字大白话解释int整数类型这一列只能填整数比如学号、编号varchar(20)字符串类型能填文字括号里是最大长度比如姓名最多20个字not null这一列不能为空必须填值比如姓名肯定不能空着primary key主键相当于这一行的身份证号唯一不重复一般都用id当主键auto_increment自动递增id不用自己填数据库会自动按1、2、3…帮你排号unique唯一约束这一列的值不能重复比如学号肯定不能两个人一样comment xxx备注相当于给列写注释方便以后看懂2.3 新手建表避坑表名、列名全部用英文小写用下划线分隔别用中文别用order、group、name这种mysql关键字当列名会报错尽量给每列设置默认值少用null后面会讲null有多坑三、insert往表里加数据建完空表就该往里面填数据了就像往花名册里登新同学信息。3.1 单行全列插入给每一列都按顺序填值值的数量和顺序必须和建表时完全对应insertintostudentsvalues(100,10000,唐三藏,null);小提示id设置了自动递增其实可以不用写。如果不指定idmysql会自动帮你生成递增的编号。3.2 指定列插入只想填某几列其他列留空或者用默认值就指定列名再插-- 只填id、学号、姓名qq号不填insertintostudents(id,sn,name)values(101,10001,孙悟空);这是开发里最常用的写法灵活不容易错。3.3 一次插多行一条一条插太慢一条语句可以插多条数据中间用逗号隔开insertintostudents(id,sn,name)values(102,20001,曹孟德),(103,20002,孙仲谋);3.4 插入避坑字符串、日期必须加英文单引号比如孙悟空数字不用值的数量、顺序必须和你指定的列严格对应所有标点符号都是英文半角中文标点直接报错四、select从表里查数据查询是日常用得最多的操作没有之一。说白了就是从表格里找出你想要的信息。为了方便演示查询我们再建一张成绩表并插入测试数据-- 建成绩表createtableexam_result(idintunsignedprimarykeyauto_increment,namevarchar(20)notnullcomment同学姓名,classvarchar(10)comment班级,chinesefloatdefault0.0comment语文成绩,mathfloatdefault0.0comment数学成绩,englishfloatdefault0.0comment英语成绩);-- 插入7条测试数据insertintoexam_result(name,class,chinese,math,english)values(唐三藏,一班,67,98,56),(孙悟空,一班,87,78,77),(猪悟能,一班,88,98,90),(曹孟德,二班,82,84,67),(刘玄德,二班,55,85,45),(孙权,三班,70,73,78),(宋公明,三班,75,65,30);4.1 查所有列select*fromexam_result;*代表所有列执行后会把整张表的所有行所有列都查出来。❌ **新手注意正式工作里别写select ***表很大的时候查所有列非常慢还会卡数据库表加列减列的时候代码容易出问题实际开发中需要哪列就写哪列4.2 只查指定列想查什么列就写什么列列的顺序可以随便换-- 只查姓名和英语成绩selectname,englishfromexam_result;4.3 给列起个别名列名太长或者是计算出来的可以给它起个好懂的外号用as或者直接空格加名字-- 计算三科总分起个别名叫总分selectname,chinesemathenglishas总分fromexam_result;-- 省略as直接空格加别名效果一样selectname,chinesemathenglish 总分fromexam_result;4.4 按条件筛选where这是查询的灵魂。说白了就是只找出符合条件的行比如“找出英语不及格的同学”。常用比较运算符每个都配一个小例子看完就会用运算符说明例子大于、大于等于、小于、小于等于select name, english from exam_result where english 60;查英语不及格的等于select name from exam_result where math 98;查数学刚好98分的!不等于select name from exam_result where math ! 98;查数学不是98分的between a and b在a和b之间包含a和bselect name, chinese from exam_result where chinese between 80 and 90;查语文80-90分的in (a,b,c)是其中任意一个select name, math from exam_result where math in (98, 78);查数学是98或者78分的is null是空的select name from students where qq is null;查没填qq号的同学is not null不是空的select name from students where qq is not null;查填了qq号的同学逻辑运算符多个条件组合的时候用运算符说明例子and并且两个条件都要满足select name from exam_result where chinese 80 and math 80;语文数学都大于80or或者满足一个就行select name from exam_result where chinese 90 or math 90;语文或数学有一门大于90not不满足select name from exam_result where not math 98;数学不是98分的⚠️ 新手必踩坑and优先级比or高多个条件混写的时候一定要用括号明确优先级。错误写法本意语文80并且姓孙或姓曹select*fromexam_resultwherechinese80andnamelike孙%ornamelike曹%;实际会变成「语文80且姓孙」或者「所有姓曹的」范围完全错了。正确写法select*fromexam_resultwherechinese80and(namelike孙%ornamelike曹%);模糊查询like只记得名字里的某个字就用模糊查询%匹配任意多个字包括0个_匹配严格的一个字-- 找所有姓孙的同学孙后面有多少字都行selectnamefromexam_resultwherenamelike孙%;-- 找名字是两个字、姓孙的同学孙后面只能有一个字selectnamefromexam_resultwherenamelike孙_;⚠️ 超级大坑null不能用判断这是90%的新手第一次都会写错的。mysql里的null是「不知道、不确定」的意思不是0也不是空字符串。错误写法永远查不到结果selectname,qqfromstudentswhereqqnull;正确写法selectname,qqfromstudentswhereqqisnull;新手记住判断是不是null固定用is null或者is not null别用等号。4.5 新手高频报错where里用别名这也是入门必踩的坑先看错误写法selectname,chinesemathenglish totalfromexam_resultwheretotal200;报错unknown column total in where clause大白话原因mysql执行的时候先执行where筛选后执行select计算别名。等where筛选的时候total这个外号还没起好所以不认。三种正确写法-- 写法1把表达式原样写一遍推荐这么写性能最好selectname,chinesemathenglish totalfromexam_resultwherechinesemathenglish200;-- 写法2用having代替where简单查询可以凑合用selectname,chinesemathenglish totalfromexam_resulthavingtotal200;-- 写法3用子查询包一层复杂查询通用selectname,totalfrom(selectname,chinesemathenglish totalfromexam_result)twheretotal200;4.6 排序order by查出来的数据太乱按指定列排个序。asc升序从小到大默认就是这个desc降序从大到小-- 按数学成绩从低到高排selectname,mathfromexam_resultorderbymath;-- 按总分从高到低排可以用别名selectname,chinesemathenglish 总分fromexam_resultorderby总分desc;也可以按多列排序先按前面的排前面相同再按后面的排-- 先按数学降序数学分数一样的话再按英语升序selectname,math,englishfromexam_resultorderbymathdesc,englishasc;4.7 分页limit数据太多一次看不完一页一页看。两种常用写法-- 直接取前3条selectid,namefromexam_resultlimit3;-- 从第0条开始取3条第1页selectid,namefromexam_resultlimit3offset0;-- 从第3条开始取3条第2页selectid,namefromexam_resultlimit3offset3;新手注意offset是从0开始数的不是从1开始。好习惯查不熟悉的表先加个limit 1试试防止表太大把数据库查卡死。五、update修改表里的数据说白了就是修改表格里已有的内容比如同学成绩登错了要改。5.1 修改指定行比如把孙悟空的数学成绩改成80分updateexam_resultsetmath80wherename孙悟空;一次改多列也可以updateexam_resultsetmath60,chinese70wherename曹孟德;也可以在原来的基础上改比如给倒数三名的数学加30分updateexam_resultsetmathmath30orderbychinesemathenglishlimit3;注意mysql不支持math 30这种简写必须写math math 30。5.2 ❗️ 致命提醒千万别忘写where-- 这行会把全表所有人的语文成绩都改成0updateexam_resultsetchinese0;这是数据库最经典的事故没有之一。忘写where就会更新全表数据毁了很难恢复。安全小技巧改数据前先把where条件复制到select里查一遍确认是你要改的那些行再执行update。5.3 更新避坑永远记得加where条件字符串值加单引号大表批量更新尽量分批别一次性锁全表六、delete删除表里的数据就是删掉表格里的行比如同学退学了从花名册里移除。6.1 删除指定行比如删掉孙悟空的成绩deletefromexam_resultwherename孙悟空;6.2 ❗️ 致命提醒千万别忘写where和update一样不加where会删掉全表所有数据-- 清空整张表非常危险deletefromexam_result;6.3 清空全表的另一种方式truncate想快速清空整张表用truncate比delete快得多truncatetableexam_result;6.4 delete和truncate的区别大白话总结一下对比项deletetruncate能不能删部分行能加where就行不能只能清空全表删错了能不能恢复能事务里可以回滚不能删了就没了速度慢逐行删大表特别慢极快直接扔掉整张表再新建自增id不重置接着原来的号继续重置从1重新开始总结删部分数据用delete确定要清空全表、不需要恢复用truncate。七、分组统计聚合函数 group by光查单行数据不够我们经常要做统计比如“每个班的平均分”“每个班有多少人”这就用到group by分组统计了。7.1 五个常用聚合函数说白了就是把一堆数据算成一个结果比如求和、求平均。函数大白话说明例子count(*)统计一共有多少行select count(*) from exam_result;统计班级总人数sum(列)求和把这一列所有数加起来select sum(math) from exam_result;算数学成绩总分avg(列)求平均值select avg(english) from exam_result;算英语平均分max(列)求最大值select max(chinese) from exam_result;找语文最高分min(列)求最小值select min(math) from exam_result;找数学最低分7.2 group by到底在干嘛你可以把group by理解成给数据打包装袋、按堆分类。没分组的时候你面对的是一行一行的学生可以查某个人的成绩。执行group by class之后数据会按班级打包成一个个独立的小组一班一袋里面装着一班所有同学的记录二班一袋里面装着二班所有同学的记录三班一袋里面装着三班所有同学的记录核心变化分组之后你面对的最小单位从「单个学生」变成了「整个班级」。你不能再直接问“这个组里学生叫什么名字”因为一个组里有好多学生你只能问“这个班有多少人”“这个班平均分多少”这种针对整个组的问题。7.3 基本用法分组 聚合分组必须和聚合函数搭配用。聚合函数就是专门用来「把一组数据算成一个数」的刚好对应分组后的组级计算。例1统计每个班有多少人selectclass,count(*)as人数fromexam_resultgroupbyclass;运行结果---------------- | class | 人数 | ---------------- | 一班 | 3 | | 二班 | 2 | | 三班 | 2 | ----------------例2统计每个班的数学成绩情况selectclass,avg(math)as数学平均分,max(math)as数学最高分,min(math)as数学最低分fromexam_resultgroupbyclass;运行结果-------------------------------------------------- | class | 数学平均分 | 数学最高分 | 数学最低分 | -------------------------------------------------- | 一班 | 91.333 | 98 | 78 | | 二班 | 84.500 | 85 | 84 | | 三班 | 69.000 | 73 | 65 | --------------------------------------------------例3多字段分组group by后面可以跟多个字段就是按多个维度层层细分。比如按班级性别分组假设有gender字段selectclass,gender,count(*)fromexam_resultgroupbyclass,gender;就是先按班级分每个班里再按性别分统计每个班每个性别的人数。7.4 新手灵魂拷问分完组原始行还在吗磁盘上的原表完完整整还在一点没动。group by只是读取数据做计算属于查询操作不会修改、删除原表里的任何数据。这条查询返回的结果里原始明细被压缩了看不到组内每一行。就像打包之后你只能看到袋子外面写的“总重量、总个数”看不到袋子里每一个水果。这也是新手最常见报错的根源-- 错误写法mysql 5.7默认直接报错selectclass,namefromexam_resultgroupbyclass;原因分组后每个班有好几个name数据库不知道该返回哪一个所以直接拒绝。旧版本关闭严格模式后会随机返回一个name结果不可控业务里绝对不能用。7.5 想要明细 分组统计用窗口函数如果既想保留所有原始学生明细又想看到每个班的平均分group by做不到要用窗口函数partition by。简单对比group by class压缩分组每组只输出1行统计结果原始明细不在结果里partition by class不压缩分组所有原始行全部保留每一行都附带本组的统计值示例了解即可属于进阶内容selectclass,name,math,avg(math)over(partitionbyclass)as班级平均分fromexam_result;输出效果---------------------------------- | class | name | math | 班级平均分 | ---------------------------------- | 一班 | 唐三藏 | 98 | 91.33 | | 一班 | 孙悟空 | 78 | 91.33 | | 一班 | 猪悟能 | 98 | 91.33 | | 二班 | 曹孟德 | 84 | 84.50 | | 二班 | 刘玄德 | 85 | 84.50 | | 三班 | 孙权 | 73 | 69.00 | | 三班 | 宋公明 | 65 | 69.00 | ----------------------------------7.6 having分组后筛选分组完了想把不符合条件的整个组去掉用having。比如找出数学平均分大于80的班级selectclass,avg(math)as数学平均分fromexam_resultgroupbyclasshavingavg(math)80;7.7 where和having的区别面试常考也是新手最容易混的一句话讲明白where是分组前筛行having是分组后筛组。打个比方公司招员工先看学历筛掉一批人where筛个体剩下的人按部门分组算每个部门的平均工资再把平均工资太高的部门整个砍掉having筛整个组对比项wherehaving什么时候执行分组之前分组之后筛什么一行一行的数据分好的整个组能用聚合函数吗不能能性能好先过滤数据少差一点最佳实践能在where里过滤的就别放到having里性能更好。八、必懂底层逻辑sql执行顺序很多新手疑惑为什么where里不能用别名为什么having里能用聚合函数答案很简单sql写的顺序和实际执行的顺序完全不一样。8.1 真实执行顺序from → where → group by → having → select → distinct → order by → limit8.2 大白话类比做菜的顺序不用死记就按做菜的逻辑想from先去菜市场买菜找到数据在哪张表where回家择菜把坏的叶子扔掉先过滤掉没用的行group by把菜分类青菜放一堆肉放一堆分组having把坏了的整堆菜扔掉筛选整个组select切菜装盘决定盘子里放什么计算列、起别名distinct挑掉重复的菜去重order by盘子摆好看点排序limit客人多先上前3盘分页顺着这个逻辑想很多问题自然就懂了为什么where不能用别名择菜的时候菜还没装盘呢哪来的菜名为什么order by能用别名都摆完盘了当然知道菜名为什么where不能用聚合函数菜都没分类怎么算每堆的平均重量8.3 懂了执行顺序有啥用不用死记各种语法规则顺着逻辑推就知道对错能自己判断sql写得好不好、快不快报错了能快速定位哪里出了问题九、新手避坑终极清单永远别写select *需要哪列写哪列update/delete一定要加where执行前先用select确认判断null用is null/is not null别用等号能where就别having先过滤再分组性能好建表尽量给默认值少用null少踩坑清空大表用truncate比delete快很多limit分页从0开始第一个数是偏移量不是页码and优先级比or高多条件记得加括号所有标点用英文半角中文标点必报错表名列名避开关键字非要用就用反引号包起来group by后select字段要么分组要么聚合别直接写非分组字段十、最后ai时代怎么学现在ai写sql又快又准很多人说不用学sql了。其实不是不用学是不用死背语法了但底层逻辑必须懂。基础的写法、函数名忘了可以查甚至让ai直接写但执行顺序、null逻辑、分组原理、性能逻辑这些东西必须理解。这是你判断ai写得对不对、排查线上问题的底气。把ai当校对工具不是答案工具。自己先写再和ai的结果对比想清楚为什么不一样进步才最快。mysql基本查询是后端开发的基本功看似简单细节和坑非常多。但只要你顺着数据流动的逻辑去理解不用死记也能牢牢掌握。多敲多练很快就能熟练。