使用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
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)。
选择哪种写法,取决于业务场景。
如果理论上同一个学生在成绩表里可能有多条记录,那就一定要用第一种写法;
如果理论上同一个学生在成绩表里只会有一条记录,那就看数据有问题时(即同一个学生出现了多个成绩),是选择抛出异常,不展示数据,还是依然要展示错误数据。
写insert语句时,最好不要直接写insert into table values(...),要把字段也列出来,insert into table (column1, column2...) values(...),这样表加了字段变了sql也不会报错
两表关联时,要考虑两边的字段都是''的情况,null与null比较结果是false,但''与''比较结果是true