1.2 外连接

在某些情况下,需要以A表为参照物 B表与之匹配,如果A表的记录在B比表中有匹配结果,那么就显示,如果没有匹配记录,那么在查询结果中B表中字段所对应的值用null填充

     A B

id bid name  age ...         id   hehe  .....

1   1   tom   11              1   南京

2   1   lili  22              2   北京

3   2   jim   23

4   3   lucy  22

1   1   tom   11   1   南京

2   1   lili  22   1   南京

3   2   jim   23   2   北京

4   3   lucy  22   null null 


1.2.1 左连接

     以左边表为参照物 到右边表进行匹配


      A as a  left join B as b on 条件

            

mysql> select
    -> *
    -> from
    -> stu_info s left join marks_info m on s.id=m.s_id ;
+----+-------+-----+---------+------+------+------+-------+
| id | sname | age | addr    | id   | s_id | c_id | marks |
+----+-------+-----+---------+------+------+------+-------+
|  1 | Tom   |  20 | beijing |    1 |    1 |    1 |    65 |
|  1 | Tom   |  20 | beijing |    2 |    1 |    2 |    60 |
|  2 | Lucy  |  23 | nanjing | NULL | NULL | NULL |  NULL |
|  3 | Lily  |  18 | beijing |    3 |    3 |    2 |    70 |
|  4 | Damat |  21 | beijing |    4 |    4 |    2 |    90 |
|  5 | jim   |  29 | nanjing |    5 |    5 |    1 |   100 |
+----+-------+-----+---------+------+------+------+-------+
6 rows in set (0.00 sec)


意思:表左连接时,以左边表为参照物,到右边表匹配,

如果左边的表在右边的表中有匹配的记录,那么就显示记录,否则在右边表的相应的字段中填充null

查询出记录至少:  左


1.2.2 右连接   right join

 以右边表为参照物 到左边表匹配

A as a  right join B as b on 条件

mysql> select
    -> *
    -> from
    -> marks_info m right join stu_info s on s.id=m.s_id ;
+------+------+------+-------+----+-------+-----+---------+
| id   | s_id | c_id | marks | id | sname | age | addr    |
+------+------+------+-------+----+-------+-----+---------+
|    1 |    1 |    1 |    65 |  1 | Tom   |  20 | beijing |
|    2 |    1 |    2 |    60 |  1 | Tom   |  20 | beijing |
| NULL | NULL | NULL |  NULL |  2 | Lucy  |  23 | nanjing |
|    3 |    3 |    2 |    70 |  3 | Lily  |  18 | beijing |
|    4 |    4 |    2 |    90 |  4 | Damat |  21 | beijing |
|    5 |    5 |    1 |   100 |  5 | jim   |  29 | nanjing |
+------+------+------+-------+----+-------+-----+---------+
6 rows in set (0.00 sec)


1.2.3 全链接   full join

全连接:mysql不支持全连接


3. 交叉连接 笛卡尔积

就是拿一个表中的记录和另一个表中的记录进行全匹配。

A  a cross join B  b  on

结果中记录:

A 记录数  *  B 记录数

                

                每个学生可能考的科目

mysql> select
    -> *
    -> from
    -> stu_info s cross join class_info c;
+----+-------+-----+---------+----+---------+
| id | sname | age | addr    | id | c_name  |
+----+-------+-----+---------+----+---------+
|  1 | Tom   |  20 | beijing |  1 | chinese |
|  1 | Tom   |  20 | beijing |  2 | english |
|  2 | Lucy  |  23 | nanjing |  1 | chinese |
|  2 | Lucy  |  23 | nanjing |  2 | english |
|  3 | Lily  |  18 | beijing |  1 | chinese |
|  3 | Lily  |  18 | beijing |  2 | english |
|  4 | Damat |  21 | beijing |  1 | chinese |
|  4 | Damat |  21 | beijing |  2 | english |
|  5 | jim   |  29 | nanjing |  1 | chinese |
|  5 | jim   |  29 | nanjing |  2 | english |
+----+-------+-----+---------+----+---------+
10 rows in set (0.00 sec)

自查询

数据都是存在一张表里,只是在查询的时候表的别名不一样

公司结构   员工 和 领导

mysql> select * from worker;
+----+------+-----+
| id | name | lid |
+----+------+-----+
|  1 | tom  |   2 |
|  2 | jim  |   3 |
|  3 | lili |   5 |
|  4 | lucy |   5 |
|  5 | jack |   6 |
|  6 | liu  |   0 |
+----+------+-----+
6 rows in set (0.00 sec)


写个sql语句,查询出所有的员工的领导

mysql> select
    -> w.id,w.name as "worker",l.name as "leader"
    -> from
    -> worker w inner join worker l on w.lid=l.id;
+----+--------+--------+
| id | worker | leader |
+----+--------+--------+
|  1 | tom    | jim    |
|  2 | jim    | lili   |
|  3 | lili   | jack   |
|  4 | lucy   | jack   |
|  5 | jack   | liu    |
+----+--------+--------+
5 rows in set (0.00 sec)

5.多表查询

是对表中的数据进行全表扫描,全表匹配

select 

*|字段列表|all|distinct|字段 as 别名,...

from 

表1 别名,表2 as 别名……where 条件

inner join   on  条件

left join    on  条件

right join   on  条件

cross join   on  条件


where 表1.字段=表2.字段 and 表2.字段……

and|or|in()|<>[!=](不等于)|between and |like|=|not in|not between|not

having

group by 

order by  字段 DESC|ASC

limit start,length

like "%abc%"

聚合函数: avg(字段) max(字段) min(字段) sum(字段) count(字段)

除了count(字段)函数外所有的聚合函数使用都必须在数值型字段上


一般和分组一起使用时,牢记先分组后计算的原则,计算的数据是分组后的针对每个小分组的计算,而不是整个表数据计算


总计一下:4月的销量总额

时间:  time() ---->int

select sum(price) from order where ispay=1 and add_time between  strtotime("2015-4-1 00:00:00") and   strtotime("2015-4-30 00:00:00")


注意:如果检索的表中都存在同一个名称字段,那么使用查询这个字段时,必须使用 表名[表的别名].字段名 来去识别字段来源于哪个表

字段别名:方便用户查看信息  select name as "姓名";

表的别名:方便用户调用表中的字段

如果一次性不能多表查询出所需要的结果,可以使用*临时表*建立一个中间表然后进行多表查询 临时表必须用 别名

查询:科目id 科目名称 平均成绩,最高成绩,最低成绩

mysql> select
    -> c.id,c.c_name,avg(m.marks) avgm,max(m.marks) maxm,min(m.marks) minm
    -> from
    -> class_info c inner join marks_info m on c.id=m.c_id
    -> group by m.c_id
    -> ;
+----+---------+---------+------+------+
| id | c_name  | avgm    | maxm | minm |
+----+---------+---------+------+------+
|  1 | chinese | 82.5000 |  100 |   65 |
|  2 | english | 73.3333 |   90 |   60 |
+----+---------+---------+------+------+
2 rows in set (0.00 sec)

这其中涉及到临时表,就是上一次查询的结果的表

查询出每个学生名字,所考课目名,科目的成绩 科目平均成绩,最高成绩,最低成绩

select

s.id,s.sname,ll.c_name,m.marks,ll.avgm,ll.maxm,ll.minm

from

stu_info s inner join marks_info m on s.id=m.s_id inner join                     (select

c.id,c.c_name,avg(m.marks) avgm,max(m.marks) maxm,min(m.marks) minm

from

class_info c inner join marks_info m on c.id=m.c_id

group by m.c_id) ll on m.c_id=ll.id

where s.id=1