查询语句的元素
join
inner join
两张表重合的部分匹配连接到一起
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 mysql> use RUNOOB; Database changed mysql> SELECT * FROM tcount_tbl; + | runoob_author | runoob_count | + | 菜鸟教程 | 10 | | RUNOOB.COM | 20 | | Google | 22 | + 3 rows in set (0.01 sec) mysql> SELECT * from runoob_tbl; + | runoob_id | runoob_title | runoob_author | submission_date | + | 1 | 学习 PHP | 菜鸟教程 | 2017-04-12 | | 2 | 学习 MySQL | 菜鸟教程 | 2017-04-12 | | 3 | 学习 Java | RUNOOB.COM | 2015-05-01 | | 4 | 学习 Python | RUNOOB.COM | 2016-03-06 | | 5 | 学习 C | FK | 2017-04-05 | + 5 rows in set (0.01 sec) mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author; + | a.runoob_id | a.runoob_author | b.runoob_count | + | 1 | 菜鸟教程 | 10 | | 2 | 菜鸟教程 | 10 | | 3 | RUNOOB.COM | 20 | | 4 | RUNOOB.COM | 20 | + 4 rows in set (0.00 sec)
left join
左边表的全部以及和右边表重合的部分
1 2 3 4 5 6 7 8 9 10 11 mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author; + | a.runoob_id | a.runoob_author | b.runoob_count | + | 1 | 菜鸟教程 | 10 | | 2 | 菜鸟教程 | 10 | | 3 | RUNOOB.COM | 20 | | 4 | RUNOOB.COM | 20 | | 5 | FK | NULL | + 5 rows in set (0.01 sec)
right join
右边表的全部以及和左边表重合的部分
1 2 3 4 5 6 7 8 9 10 11 mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author; + | a.runoob_id | a.runoob_author | b.runoob_count | + | 1 | 菜鸟教程 | 10 | | 2 | 菜鸟教程 | 10 | | 3 | RUNOOB.COM | 20 | | 4 | RUNOOB.COM | 20 | | NULL | NULL | 22 | + 5 rows in set (0.01 sec)
exists 和 in
1 2 3 4 5 6 7 #对B查询涉及id,使用索引,故B表效率高,可用大表 -->外小内大 select * from A where exists (select * from B where A.id=B.id);#对A查询涉及id,使用索引,故A表效率高,可用大表 -->外大内小 select * from A where A.id in (select id from B);
区别
1、exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的使用exists,可加快效率;
以上面为例,也就是A.id一个一个遍历,如果有A.id=B.id的就筛选出来
2、in是把外表和内表做hash连接,先查询内表,再把内表结果与外表匹配,对外表使用索引(外表效率高,可用大表),而内表多大都需要查询,不可避免,故外表大的使用in,可加快效率。
having
having字句可以让我们筛选成组后的各种数据
当用到了聚合函数后,就不能通过where来筛选了,因为表中并没有这样的数据。
举例:
1 2 3 4 SELECT region, SUM (population), SUM (area)FROM bbcGROUP BY regionHAVING SUM (area)>1000000
执行顺序
(1) from
(2) on(跟join一起用,用来筛选右表,比如on right.id = 10。那么在join的时候 只有id=10的右表信息会合并过来)
(3) join
(4) where
(5) group by(开始使用select中的别名,后面的语句中都可以使用)
(6) avg,sum…
(7) having
(8) select
(9) distinct
(10) order by
所有的查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。