当前位置: 首页 > 科技观察

7个超实用的MySQL语句写法,让同事眼前一亮!

时间:2023-03-13 19:29:33 科技观察

在编写SQL的时候,我经常灵活运用一些SQL语句的编写技巧,可以大大简化程序逻辑。减少程序与数据库的交互次数,有利于数据库的高可用,也能说明你的SQL很厉害,会让同事眼前一亮。1.插入或替换如果我们要插入一条新记录(INSERT),但如果该记录已经存在,则先删除原来的记录,再插入新记录。场景示例:该表存储了每个客户最新的交易订单信息。要求保证单个用户的数据不重复录入,执行效率最高,与数据库的交互最少,以支撑数据库的高可用。此时可以使用“REPLACEINTO”语句,这样就不用先查询,再决定是否删除再插入。“REPLACEINTO”语句根据唯一索引或主键来判断唯一性(是否存在)。“REPLACEINTO”语句根据唯一索引或主键来判断唯一性(是否存在)。“REPLACEINTO”语句根据唯一索引或主键来判断唯一性(是否存在)。注意:如下SQL所示,用户名字段需要建立唯一索引(Unique),transId设置可以自增。--充值20分REPLACEINTOlast_transaction(transId,username,amount,trans_time,remark)VALUES(null,'chenhaha',30,'2020-06-1120:00:20','会员充值');--购买时间21点皮肤REPLACEINTOlast_transaction(transId,username,amount,trans_time,remark)VALUES(null,'chenhaha',100,'2020-06-1121:00:00','购买盲僧至尊拳皮肤');如果username='chenhaha'的记录不存在,则REPLACE语句会插入一条新记录(先充值),否则会删除username='chenhaha'的当前记录,然后插入一条新记录。id不要给具体的值,否则会影响SQL的执行,除非业务有特殊需求。2.插入或更新如果我们要插入一条新记录(INSERT),但是如果记录已经存在,则更新记录,这时候,可以使用“INSERTINTO...ONDUPLICATEKEYUPDATE...”语句:场景示例:该表存储用户的历史充值金额。如果是第一次充值,添加一条新的数据。如果用户之前充值过,则累计历史充值金额。需要保证单个用户的数据不被重复录入。这时,可以使用“INSERTINTO...ONDUPLICATEKEYUPDATE...”语句。注意:如上,“INSERTINTO...ONDUPLICATEKEYUPDATE...”语句是根据唯一索引或主键来判断唯一性(是否存在)。如下SQL所示,用户名字段需要建立唯一索引(Unique),transId设置可以自增。--用户chenhaha充值30元购买会员ONDUPLICATEKEYUPDATEtotal_amounttotal_amount=total_amount+30,last_transTime='2020-06-1120:00:20',last_remark='rechargemember';--用户陈哈哈充值100元购买盲神拳皮肤INSERTINTOtotal_transaction(t_transId,username,total_amount,last_transTime,last_remark)VALUES(null,'chenhaha',100,'2020-06-1120:00:20','购买盲僧至尊拳皮肤')ONDUPLICATEKEYUPDATEtotal_amounttotal_amount=total_amount+100,last_transTime='2020-06-1121:00:00',last_remark='购买盲僧至尊拳皮肤';如果username='chenhaha'的记录不存在,INSERT语句将插入一条新记录,否则,将更新username='chenhaha'的当前记录,更新字段由UPDATE指定。3.Insertorignore如果我们想插入一条新记录(INSERT),但是如果这条记录已经存在,那么忽略它什么也不做。这时候可以使用INSERTIGNOREINTO...语句:场景很多,不再举例重复。注意:如上,“INSERTIGNOREINTO...”语句是根据唯一索引或主键来判断唯一性(是否存在)。需要在用户名字段上创建唯一索引(Unique),transId设置可以自增。--用户第一次添加INSERTIGNOREINTOusers_info(id,username,sex,age,balance,create_time)VALUES(null,'chenhaha','male',12,0,'2020-06-1120:00:20');--二次加法,直接忽略INSERTIGNOREINTOusers_info(id,username,sex,age,balance,create_time)VALUES(null,'chenhaha','male',12,0,'2020-06-1121:00:20');如果username='chenhaha'的记录不存在,INSERT语句会插入一条新记录,否则不执行任何操作。4.SQL中的if-else判断语句众所周知,if-else判断在任何地方都非常有用。在SQL语句中,“CASEWHEN...THEN...ELSE...END”语句可用于增删改查各种语句。举个场景:妇女节大礼包,2020年新注册用户,所有成年女性账号送10元红包,其他用户送5元红包,自动充值。分享:SpringBoot学习笔记。示例语句如下:--发送红包语句UPDATEusers_infouSETu.balance=CASEWHENu.sex='female'andu.age>18THENu.balance+10ELSEu.balance+5endWHEREu.create_time>='2020-01-01'场景2:有一个学生高考成绩表需要列出成绩。650以上为重点大学,600-650为一科,500-600为二科,400-500为三科,400以下为专科;原始测试数据如下:查询语句:SELECT*,casewhentotal_score>=650THEN'重点大学'whentotal_score>=600andtotal_score<650THEN'one'whentotal_score>=500andtotal_score<600THEN'two'whentotal_score>=400andtotal_score<500THEN'three'else'college'endasstatus_student_scorest;指定数据快照或备份如果要对表进行快照,即将当前表的数据复制到新表中,可以结合CREATETABLE和SELECT:--对class_id=的记录进行快照1(一个班级),并存储为新表students_of_class1:CREATETABLEStudents_of_class1SELECT*FROMstudentWHEREclass_id=1;新建的表结构与SELECT使用的表结构完全一样。推荐阅读:MySQL数据库开发的36条军规!6、写入查询结果集如果需要将查询结果集写入表中,可以结合INSERT和SELECT,直接将SELECT语句的结果集插入到指定表中。例如创建一个统计表statistics,记录每个班级的平均成绩:CREATETABLEstatistics(idBIGINTNOTNULLAUTO_INCREMENT,class_idBIGINTNOTNULL,averageDOUBLENOTNULL,PRIMARYKEY(id));然后,我们可以用一条语句写出每个班级的平均成绩:INSERTINTOstatistics(class_id,average)SELECTclass_id,AVG(score)FROMstudentsGROUPBYclass_id;保证INSERT语句的列和SELECT语句的列可以一一对应,然后查询结果就可以直接保存到统计表中了:SELECT*FROMstatistics;+----+----------+------------+|id|class_id|average|+----+------------+------------+|1|1|475.5||2|2|473.33333333||3|3|488??.66666666|+----+------------+-------------+3rowsinset(0.00sec)7.强制使用指定索引查询时,数据库系统会自动分析查询语句,选择最合适的索引。但是很多时候,数据库系统的查询优化器不一定总能使用到最优的索引。如果我们知道如何选择索引,我们可以使用FORCEINDEX强制查询使用指定的索引。例如:SELECT*FROMstudentsFORCEINDEX(idx_class_id)WHEREclass_id=1ORDERBYidDESC;指定索引的前提是索引idx_class_id必须存在。另外,关注公众号Java技术栈,后台回复:面试,可以拿到我整理的MySQL系列面试题及答案,很全。