mysql sql语句常见踩坑点

使用limit时,一定要搭配使用order by,否则结果难以预料,除非你只关心数量,不关心内容
(可以了解下mysql不加order by时默认的排序规则)


distinct后面有多列时(比如distinct column1, column2...), distinct是对后面所有列同时做去重,而不是只对column1做去重。
如果你以为distinct column1, column2...查出来的column1只出现一次,那结果就与你的预期不符


union与union all区别
union会排除重复记录,相当于distinct,同时会按默认规则排序;
union all不会去重,也不会排序
使用union还是union all,取决于业务场景需不需要对结果去重和排序。


任何字段与null比较,结果都是false,即使是null与null比较。
所以多个字段关联查询时,如果其中一个字段为null,关联结果就是false,比如null = null and 1 = 1。

在写多字段关联的sql时,需要结合业务场景,考虑当其中一个字段为null时,本次关联还生不生效。

比如a和b都是学生表,两个表都有s_id(学生id)和c_id(班级id)列,求两个表共同的学生(学生id和班级id同时相等时,判定为同一个学生),sql为:

select * from a, b where a.s_id = b.s_id and a.c_id = c.c_id

假如有一个学生,在a、b表都存在,但是c_id为空(比如该学生未排到具体班级),那么上面的sql就会漏掉该学生,需要把sql调整为:

select * from a, b 
where 
((a.c_id is null and b.c_id is null) or a.c_id = b.c_id)
and a.s_id = c.s_id


left join注意事项
https://www.jianshu.com/p/d0f9b3c75b0d


student_info表是学生信息表,student_score表是学生成绩表,两表通过s_id(学生id)字段关联,编写sql查询学生成绩,有以下两种写法:

第一种写法

select sc.score
from student_info si, student_score sc
where si.s_id = sc.s_id

第二种写法

select 
    (select sc.score from student_score sc where si.s_id = sc.s_id)
from student_info si

上面两种写法有什么区别?
第一种写法,如果si.s_id = sc.s_id这里关联出多条记录,最后结果就会有多条,不会报错。
第二种写法,如果si.s_id = sc.s_id这里关联出多条记录,sql就会报错,程序会抛异常(除非在后面加上limit 1)。

选择哪种写法,取决于业务场景
如果理论上同一个学生在成绩表里可能有多条记录,那就一定要用第一种写法;
如果理论上同一个学生在成绩表里只会有一条记录,那就看数据有问题时(即同一个学生出现了多个成绩),是选择抛出异常,不展示数据,还是依然要展示错误数据。


not in可能丢失数据
https://www.jianshu.com/p/5898e54cdec9


写insert语句时,最好不要直接写insert into table values(...),要把字段也列出来,insert into table (column1, column2...) values(...),这样表加了字段变了sql也不会报错


两表关联时,要考虑两边的字段都是''的情况,null与null比较结果是false,但''与''比较结果是true


推荐阅读更多精彩内容