[mysql基础文档]-30-左右内联查询

引言

左右连接查询和内联查询的工作方式很类似,所不同的是,左右连接查询会将左值或右值作为基准值进行对比。

文章目录

0×1.如何使用left join和right join查询

使用上一篇文章inner join查询实例中所创建的表A和B来演示左右联合查询,建表语法请参考上一篇文章,这里仅给出表结构:

                    
                    mysql> select * from A;
                    +-----+-------+
                    | aid | aname |
                    +-----+-------+
                    |   1 | susam |
                    |   2 | jenny |
                    |   3 | mary  |
                    +-----+-------+

                    mysql> select * from B;
                    +-----+--------+
                    | bid | bname  |
                    +-----+--------+
                    |   2 | tom    |
                    |   3 | john   |
                    |   4 | george |
                    +-----+--------+

                    --左联接查询,在这个实例中A表是"A left join B"这个表达式的左值,作为参照表使用A表aid列连接B表bid列,在这个过程中,将列出所有A表下面每个aid字段所对应的记录,当B表对应的bid中没有字段匹配的时候,用NULL填充,有人可能会问,为什么没有4,因为用左值作为参考,aid中没有4
                    mysql> select * from A left join B on A.aid=B.bid;
                    +-----+-------+------+-------+
                    | aid | aname | bid  | bname |
                    +-----+-------+------+-------+
                    |   1 | susam | NULL | NULL  |
                    |   2 | jenny |    2 | tom   |
                    |   3 | mary  |    3 | john  |
                    +-----+-------+------+-------+

                    --右连接查询同理,顾名思义,B是"A right join B"这个表达式的右值,所以用B作为参考表,A中不存在的对应记录用NULL填充
                    mysql> select * from A right join B on A.aid=B.bid;
                    +------+-------+-----+--------+
                    | aid  | aname | bid | bname  |
                    +------+-------+-----+--------+
                    |    2 | jenny |   2 | tom    |
                    |    3 | mary  |   3 | john   |
                    | NULL | NULL  |   4 | george |
                    +------+-------+-----+--------+
                    
                    

0×2.联合查询综合经典实例

实例1,创建一个联合查询,将"mysql基础文档-24-select查询基础"第一部分所创建的cellphone表,请参考:[cellphone数据表],以及"mysql基础文档-28-子查询"第二部分中创建的category表,请参考:[category数据表],cellphone表中的goods_name,category表中的cat_id,cat_name,这三列查询并显示成一个结果集

                    
                    --使用内联查询,将category的cat_id列同cellphone的cat_id列连接起来,
                    mysql> select category.cat_id,category.cat_name,cellphone.goods_name
                        -> from
                        -> cellphone inner join category
                        -> on
                        -> category.cat_id=cellphone.cat_id;
                    +--------+----------+--------------+
                    | cat_id | cat_name | goods_name   |
                    +--------+----------+--------------+
                    |      1 | XiaoMi   | hongMI2a     |
                    |      1 | XiaoMi   | MInote       |
                    |      1 | XiaoMi   | hongMI2      |
                    |      1 | XiaoMi   | MI4          |
                    |      2 | Samsung  | GalaxyN9200  |
                    |      3 | Apple    | iPhone6A1586 |
                    |      4 | Meizu    | MeizuNote2   |
                    |      5 | Huawei   | Huawei4X     |
                    |      2 | Samsung  | GalaxyG9250  |
                    |      5 | Huawei   | Huawei4A     |
                    |      4 | Meizu    | MX5          |
                    |      3 | Apple    | iPhone5s     |
                    |      2 | Samsung  | GalaxyN9109W |
                    |      4 | Meizu    | MX4          |
                    |      3 | Apple    | iPhone4s     |
                    |      5 | Huawei   | Huawei6      |
                    |      3 | Apple    | iPhone6s     |
                    |      4 | Meizu    | MX4Pro       |
                    |      2 | Samsung  | GalaxyS6     |
                    |      5 | Huawei   | Huawei7      |
                    +--------+----------+--------------+

                    --有兴趣的朋友可以试着显示这张完整的内联表
                    mysql> select * from cellphone inner join category on category.cat_id=cellphone.cat_id;

                    --如果仅需要筛选出cat_id为3的完整记录,可以如下,这里要注意,当内联后的表中包含同名列时,使用时需要指定表前缀(category.cat_id)
                    mysql> select *
                        -> from
                        -> cellphone inner join category
                        -> on
                        -> category.cat_id=cellphone.cat_id
                        -> where
                        -> category.cat_id=3;
                    
                    

实例2,一道真实的内联查询面试题

现有两张表如下:

                    
                    mysql> create table team(tid tinyint,tname char(3));
                    mysql> insert into team values
                        -> (1,'T1'),
                        -> (2,'T2'),
                        -> (3,'T3');

                    mysql> create table mat(cid tinyint unsigned,h tinyint,g tinyint,scoring char(10),sdate date);
                    mysql> insert into mat values
                        -> (1,1,2,'2:0','2015-05-12'),
                        -> (2,2,3,'1:2','2015-06-01'),
                        -> (3,3,1,'2:5','2015-06-15'),
                        -> (4,2,1,'3:2','2015-07-15');

                    --球队id和球队名称表team
                    mysql> select * from team;
                    +------+-------+
                    | tid  | tname |
                    +------+-------+
                    |    1 | T1    |
                    |    2 | T2    |
                    |    3 | T3    |
                    +------+-------+

                    --球队比赛日期表,cid总比赛场数列,h表示主场,g表示客场,主客场列的值分别对应了team表的tid值,scoring是单场比赛得分,sdate是比赛日期
                    mysql> select * from mat;
                    +------+------+------+---------+------------+
                    | cid  | h    | g    | scoring | sdate      |
                    +------+------+------+---------+------------+
                    |    1 |    1 |    2 | 2:0     | 2015-05-12 |
                    |    2 |    2 |    3 | 1:2     | 2015-06-01 |
                    |    3 |    3 |    1 | 2:5     | 2015-06-15 |
                    |    4 |    2 |    1 | 3:2     | 2015-07-15 |
                    +------+------+------+---------+------------+
                    
                    

要求,查询出"2015-06-01"至"2015-07-01"之间所有比赛记录,返回结果集格式要求"T1 2:0 T2 2015-06-01"。

                    
                    --还记得以前的分步思想吗?先用mat表的h列对应team表的tid列进行一次内联查询,使用as将第一个连接的team表命名为t1,t1中的tname顺序对应了主场的h值
                    mysql> select *
                        -> from
                        -> mat inner join team as t1
                        -> on
                        -> mat.h=t1.tid;
                    +------+------+------+---------+------------+------+-------+
                    | cid  | h    | g    | scoring | sdate      | tid  | tname |
                    +------+------+------+---------+------------+------+-------+
                    |    1 |    1 |    2 | 2:0     | 2015-05-12 |    1 | T1    |
                    |    2 |    2 |    3 | 1:2     | 2015-06-01 |    2 | T2    |
                    |    3 |    3 |    1 | 2:5     | 2015-06-15 |    3 | T3    |
                    |    4 |    2 |    1 | 3:2     | 2015-07-15 |    2 | T2    |
                    +------+------+------+---------+------------+------+-------+

                    --对上面的步骤再加工,将上面这一步的结果集作为一张完整的表,再次和team表进行内联查询,使用team的tid对应mat表的g列,从而可以得到客场作战的tname顺序,将第二个连接的team表命名为t2,虽然结果中有四列相同的tid和tname,但是大家要明白前面两列是t1表的,后面两列是t2表的,select筛选的时候会用到
                    mysql> select *
                        -> from
                        -> mat inner join team as t1
                        -> on
                        -> mat.h=t1.tid
                        -> inner join team as t2
                        -> on
                        -> mat.g=t2.tid;
                    +-----+---+---+---------+------------+------+-------+------+-------+
                    | cid | h | g | scoring | sdate      | tid  | tname | tid  | tname |
                    +-----+---+---+---------+------------+------+-------+------+-------+
                    |   1 | 1 | 2 | 2:0     | 2015-05-12 |    1 | T1    |    2 | T2    |
                    |   2 | 2 | 3 | 1:2     | 2015-06-01 |    2 | T2    |    3 | T3    |
                    |   3 | 3 | 1 | 2:5     | 2015-06-15 |    3 | T3    |    1 | T1    |
                    |   4 | 2 | 1 | 3:2     | 2015-07-15 |    2 | T2    |    1 | T1    |
                    +-----+-------+---------+------------+------+-------+------+-------+

                    --总表出来后,最后一次加工,按照题目要求的格式,写出select后面的部分代替星号,筛选出对应列和时间范围即可,cid列可写可不写
                    mysql> select cid,t1.tname as hname,scoring,t2.tname as gname,sdate
                        -> from
                        -> mat inner join team as t1
                        -> on
                        -> mat.h=t1.tid
                        -> inner join team as t2
                        -> on
                        -> mat.g=t2.tid
                        -> where between '2015-06-01' and '2015-07-01';
                    +------+-------+---------+-------+------------+
                    | cid  | tname | scoring | gname | sdate      |
                    +------+-------+---------+-------+------------+
                    |    2 | T2    | 1:2     | T3    | 2015-06-01 |
                    |    3 | T3    | 2:5     | T1    | 2015-06-15 |
                    +------+-------+---------+-------+------------+