用两个表(a_table、b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内链接、外链接( 左(外)链接、右(外)链接、全(外)链接)。php
MySQL版本:Server version: 5.6.31 MySQL Community Server (GPL)html
数据库表:a_table、b_tablemysql
主题:内链接、左链接(左外链接)、右链接(右外链接)、全链接(全外链接)sql
前提
建表语句:
CREATE TABLE `a_table` ( `a_id` int(11) DEFAULT NULL, `a_name` varchar(10) DEFAULT NULL, `a_part` varchar(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `b_table` ( `b_id` int(11) DEFAULT NULL, `b_name` varchar(10) DEFAULT NULL, `b_part` varchar(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8

说明:组合两个表中的记录,返回关联字段相符的记录,也就是返回两个表的交集(阴影)部分。

2、左链接(左外链接)


3、右链接(右外链接)


4、全链接(全外链接)
5、补充,MySQL如何执行关联查询
outer_iter = iterator over tbl1 where col1 in (5, 6) outer_row = outer_iter.next while outer_row inner_iter = iterator over tbl2 where col3 = outer_row.col3 inner_row = inner_iter.next while inner_row output [ outer_row.col1, inner_row.col2] inner_row = inner_iter.next end outer_row = outer_iter.next end
select tbl1.col1, tbl2.col2 from tbl1 left outer join tbl2 using(col3) where tbl1.col1 in (5, 6);
outer_iter = iterator over tbl1 where col1 in (5, 6) outer_row = outer_iter.next while outer_row inner_iter = iterator over tbl2 where col3 = outer_row.col3 inner_row = inner_iter.next if inner_row while inner_row output [ outer_row.col1, inner_row.col2] inner_row = inner_iter.next end else output [ outer_row.col1, null] end outer_row = outer_iter.next end
1.JOIN和UNION区别
join 是两张表作交连后里面条件相同的部分记录产生一个记录集,
union是产生的两个记录集(字段要同样的)并在一块儿,成为一个新的记录集。
JOIN用于按照ON条件联接两个表,主要有四种:
INNER JOIN:内部联接两个表中的记录,仅当至少有一个同属于两表的行符合联接条件时,内联接才返回行。我理解的是只要记录不符合ON条件,就不会显示在结果集内。
LEFT JOIN / LEFT OUTER JOIN:外部联接两个表中的记录,并包含左表中的所有记录。若是左表的某记录在右表中没有匹配记录,则在相关联的结果集中右表的全部选择列表列均为空值。理解为即便不符合ON条件,左表中的记录也所有显示出来,且结果集中该类记录的右表字段为空值。
RIGHT JOIN / RIGHT OUTER JOIN:外部联接两个表中的记录,并包含右表中的所有记录。简单说就是和LEFTJOIN反过来。
FULL JOIN / FULL OUTER JOIN:完整外部联接返回左表和右表中的全部行。就是LEFTJOIN和RIGHTJOIN和合并,左右两表的数据都所有显示。数据库
JOIN的基本语法:
Select table1.* FROM table1 JOIN table2 ON table1.id=table2.idmarkdown
sql写法
内链接innerjoin:
SELECT msp.name, party.name
FROM msp JOIN party ON party=code
或
SELECT msp.name, party.name
FROM msp inner JOIN party ON party=code
左链接leftjoin :
SELECT msp.name, party.name
FROM msp LEFT JOIN party ON party=code
右链接rightjoin :
SELECT msp.name, party.name
FROM msp RIGHT JOIN party ON msp.party=party.codepost
全链接(fulljoin):
SELECT msp.name, party.name
FROM msp FULL JOIN party ON msp.party=party.code性能
UNION运算符
将两个或更多查询的结果集组合为单个结果集,该结果集包含联合查询中的全部查询的所有行。UNION的结果集列名与UNION运算符中第一个Select语句的结果集的列名相同。另外一个Select语句的结果集列名将被忽略。
其中两种不一样的用法是UNION和UNIONALL,区别在于UNION从结果集中删除重复的行。若是使用UNIONALL 将包含全部行而且将不删除重复的行。测试
UNION和UNIONALL的区别:
union 检查重复
union all 不作检查
好比select 'a' union select 'a' 输出就是一行 a
好比select 'a' union all select 'a' 输出就是两行 aatom
2.经过下面的例子,能够清晰的看出和理解2者的区别
实例1典型的二表链接演示
假定有两个表Table1和Table2,其包含的列和数据分别如表1.1和表1.2所示。
表1.1Table1数据库表
ColumnA |
ColumnB |
ColumnC |
X1 |
Y1 |
Z1 |
X2 |
Y2 |
Z2 |
X3 |
Y3 |
Z3 |
表1.2Table2数据库表
ColumnA |
ColumnD |
ColumnE |
X1 |
D1 |
E1 |
X2 |
D2 |
E2 |
X3 |
D3 |
E3 |
Table1和Table2表共有的列为ColumnA,若是经过ColumnA列的值链接Table1和Table2两个表,即链接条件为Table1.ColumnA=Table2.ColumnA,此时获得的链接结果如表1.3所示。
表1.3 链接Table1和Table2表
ColumnA |
ColumnB |
ColumnC |
ColumnD |
ColumnE |
X1 |
Y1 |
Z1 |
D1 |
E1 |
X2 |
Y2 |
Z2 |
D2 |
E2 |
X3 |
Y3 |
Z3 |
D3 |
E3 |
上述链接过程的实现代码可表示以下:SELECT* FROM Table1 JOIN Table2 ON Table1.ColumnA=Table2.columnA
实例2 典型的二表记录的UNION运算
假定有两个表Table3和Table4,其包含的列和数据分别如表2.1和表2.2所示。
表2.1Table3数据库表
ColumnA |
ColumnB |
ColumnC |
X1 |
Y1 |
Z1 |
X2 |
Y2 |
Z2 |
X3 |
Y3 |
Z3 |
表2.2Table4数据库表、
ColumnA |
ColumnD |
ColumnE |
X4 |
Y4 |
Z4 |
X5 |
Y5 |
Z5 |
X6 |
Y6 |
Z6 |
Table3表和Table4表具备相同的列结构,列数也要相同,列名能够不一样,以第一个表的列名为新表的列名,所以可使用UNION运算符链接两个表的记录集,获得的链接结果如表2.3所示。
表2.3 使用UNION链接Table3表和Table4表的记录
ColumnA |
ColumnB |
ColumnC |
X1 |
Y1 |
Z1 |
X2 |
Y2 |
Z2 |
X3 |
Y3 |
Z3 |
X4 |
Y4 |
Z4 |
X5 |
Y5 |
Z5 |
X6 |
Y6 |
Z6 |
上述链接过程的实现代码可表示以下:SELECT * FROM Table3 UNION SELECT *FROMTable4
left join on +多条件与where区别
重点
先匹配,再筛选where条件。
本文将经过几个例子说明二者的差异。
表1:product
id | amount |
---|---|
1 | 100 |
2 | 200 |
3 | 300 |
4 | 400 |
表2:product_details
id | weight | exist |
---|---|---|
2 | 22 | 0 |
4 | 44 | 1 |
5 | 55 | 0 |
6 | 66 | 1 |
1. 单个条件
select * from product a left join product_details b on a.id = b.id
以左表为准匹配,结果:
id | amount | id | weight | exist |
---|---|---|---|---|
1 | 100 | null | null | null |
2 | 200 | 2 | 22 | 0 |
3 | 300 | null | null | null |
4 | 400 | 4 | 44 | 1 |
2. 条件写在on 与where区别
查询1:
SELECT * FROM product LEFT JOIN product_details ON (product.id = product_details.id) AND product.amount=200;
结果:
id | amount | id | weight | exist |
---|---|---|---|---|
1 | 100 | null | null | null |
2 | 200 | 2 | 22 | 0 |
3 | 300 | null | null | null |
4 | 400 | null | null | null |
把on的全部条件做为匹配条件,不符合的右表都为null。
查询2:
SELECT * FROM product LEFT JOIN product_details ON (product.id = product_details.id) WHERE product.amount=200;
id | amount | id | weight | exist |
---|---|---|---|---|
2 | 200 | 2 | 22 | 0 |
匹配完再筛选,结果只有一条记录。
3. where XXX is null 状况
使用该语句表示:删除掉不匹配on后面条件的记录。
where XXX is not null 则表示筛选出符合on后面条件的记录。
经常使用于只须要左表的数据,好比count id这类。
SELECT a.* FROM product a LEFT JOIN product_details b ON a.id=b.id AND b.weight!=44 AND b.exist=0 WHERE b.id IS NULL;
结果:
id | amount |
---|---|
1 | 100 |
3 | 300 |
4 | 400 |
能够直观看出,只有id=2的纪录彻底匹配上三个条件,因此筛除这条纪录,另三条保留,此时这三条纪录的右表均为null。
筛选出不符合on后面条件的,即 !(a.id=b.id AND b.weight!=44 AND b.exist=0).
!(a.id=b.id AND || !(b.weight!=44) || !(b.exist=0).
(a.id != b.id AND || (b.weight = 44) || ( b.exist! = 0).
逻辑 AND 和 逻辑 OR表达式,其操做数是从左到右求值的。若是第一个参数作够判断操做结果,那么第二个参数便不会被计算求值(短路效果)。
下面语句与该语句效果相同:(这里相同指的是最后只用到左表数据,如果将右表数据写出来是不同的)
SELECT a.* FROM product a LEFT JOIN product_details b ON a.id=b.id WHERE b.id is null OR b.weight=44 OR b.exist=1;
将on的否认条件写在where后,效果相同。
注:
若是你使用 LEFT JOIN 来寻找在一些表中不存在的记录,你须要作下面的测试:WHERE 部分的 col_name IS NULL,MYSQL 在查询到一条匹配 LEFT JOIN 条件后将中止搜索更多行(在一个特定的组合键下)。