最近在做各类小应用,用到了MYSQL,有时候会用到一些比较复杂的嵌套查询,在研究怎么通过SQL实现这些。
假设下面这张表(stu)描述学生的基本信息:
id | name | grade |
---|---|---|
1 | Jim | 7 |
2 | Tom | 8 |
3 | Cake | 9 |
… | … | … |
另外一张表(sco)描述学生的成绩信息:
stu_id | subject | score |
---|---|---|
1 | math | 78 |
2 | math | 83 |
3 | physics | 90 |
… | … | … |
现在想查询七年级学生的数学成绩,那么sql语句应该这么写:
select * from stu left join sco on stu.id = sco.stu_id where stu.grade = 7
and sco.subject = "math";
两个表都有过滤条件,博主在实际应用场景下,两个表要复杂得多,而且过滤条件也多,于是在想有没有办法先select出两张表,然后再join。从性能上说,先过滤也有利于后续join的过程。当然,数据库对这些肯定有相应优化。我们还是回归到一个基本问题, 两个子查询怎么样进行join呢?
select * from
(select * from stu where grade = 7) s
left join
(select * from sco where subject = "math") t
on s.id = t.stu_id;
注意在上面的例子当中,两个子查询的写法,查询语句括起来,紧跟一个表的临时命名。
再写个复杂的例子,我们知道mysql不支持全外连接,如果要对上面的表进行全外连接,怎么办呢?
思路也简单,先左外连接,再右外连接,最后求并。
select * from
(select * from stu where grade = 7) s
left join
(select * from sco where subject = "math") t
on s.id = t.stu_id
union
select * from
(select * from stu where grade = 7) s
right join
(select * from sco where subject = "math") t
on s.id = t.stu_id
单从语句上看起来,有点复杂。事实上,sql功能强大,可以实现许多复杂业务的查询。在实际场景,其实很容易遇到这样的情形。