sql 各种 Join用法详解
在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。连接的全部意义在于在水平方向上合并两个数据集合(通常是表),并产生一个新的结果集合,其方法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。SQL提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。
不同的 SQL JOIN
连接类型 | 定义 |
Inner Join | 内连接是最常见的一种连接,它也被称为普通连接,只连接匹配的行(仅对满足连接条件的CROSS中的列)。它又分为等值连接(连接条件运算符为"=")和不等值连接(连接条件运算符不为"=",例如between...and)。 |
Full Outer Join | FULL JOIN 会从左表 和右表 那里返回所有的行。如果其中一个表的数据行在另一个表中没有匹配的行,那么对面的数据用NULL代替 |
Left Outer Join | LEFT JOIN返回左表的全部行和右表满足ON条件的行,如果左表的行在右表中没有匹配,那么这一行右表中对应数据用NULL代替。 |
Right Outer Join | RIGHT JOIN返回右表的全部行和左表满足ON条件的行,如果右表的行在左表中没有匹配,那么这一行左表中对应数据用NULL代替。 |
Cross Join | CROSS对两个表执行笛卡尔乘积。它为左表行和右表行的每种可能的组合返回一行。返回(左表行数*右表行数)行的表。 |
Appendix Natural Join |
自然连接是一种特殊的等值连接,在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。 |
Appendix 自连接 |
某个表和其自身连接,常用在同一表内不同数据间对同一列的比较 |
self join 常用在同一表内不同数据间对同一列的比较
select a.emp_no,a.emp_name,b.emp_no,b.emp_name,a.date_hired from
employee ajoin employee b
on (a.emp_no!=b.emp_no and a.date_hired=b.date_hired)
order by a.date_hired
这样会重复数据,只要加上一句 and a.emp_name>b.emp_name
UNION
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。
SELECT column_name(s) FROM table_name1 UNION ALL SELECT column_name(s) FROM table_name2另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
UNION 实例:
列出所有在中国和美国的不同的雇员名:
SELECT E_Name FROM Employees_ChinaUNION
SELECT E_Name FROM Employees_USA
UNION ALL实例:
列出在中国和美国的所有的雇员:
SELECT E_Name FROM Employees_ChinaUNION ALL
SELECT E_Name FROM Employees_USA
下面转自:http://blog.sina.com.cn/s/blog_7e5f32ff0102wbwc.html
性能优化
1.显示(explicit) inner join VS 隐式(implicit) inner join
如:
select * from table a inner join table b on a.id = b.id;
VS
select a.*, b.* from table a, table b where a.id = b.id;
我在数据库中比较(10w数据)得之,它们用时几乎相同,第一个是显示的inner join,后一个是隐式的inner join。
2.left join/right join VS inner join
尽量用inner join.避免 LEFT JOIN 和 NULL.
在使用left join(或right join)时,应该清楚的知道以下几点:
(1). on与 where的执行顺序
ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行。如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。
所以我们要注意:在使用Left (right) join的时候,一定要在先给出尽可能多的匹配满足条件,减少Where的执行。如:
PASS
select * from A inner join B on B.name = A.name left join C on C.name = B.name left join D on D.id = C.id where C.status>1 and D.status=1;
Great
select * from A inner join B on B.name = A.name left join C on C.name = B.name and C.status>1 left join D on D.id = C.id and D.status=1
从上面例子可以看出,尽可能满足ON的条件,而少用Where的条件。从执行性能来看第二个显然更加省时。
(2).注意ON 子句和 WHERE 子句的不同
如作者举了一个列子:
mysql> SELECT * FROM product LEFT JOIN product_details ON (product.id = product_details.id) AND product_details.id=2; +----+--------+------+--------+-------+ | 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 | +----+--------+------+--------+-------+ 4 rows in set (0.00 sec) mysql> SELECT * FROM product LEFT JOIN product_details ON (product.id = product_details.id) WHERE product_details.id=2; +----+--------+----+--------+-------+ | id | amount | id | weight | exist | +----+--------+----+--------+-------+ | 2 | 200 | 2 | 22 | 0 | +----+--------+----+--------+-------+ 1 row in set (0.01 sec)
从上可知,第一条查询使用 ON 条件决定了从 LEFT JOIN的 product_details表中检索符合的所有数据行。第二条查询做了简单的LEFT JOIN,然后使用 WHERE 子句从 LEFT JOIN的数据中过滤掉不符合条件的数据行。
(3).尽量避免子查询,而用join
往往性能这玩意儿,更多时候体现在数据量比较大的时候,此时,我们应该避免复杂的子查询。如下:
PASS
insert into t1(a1) select b1 from t2 where not exists(select 1 from t1 where t1.id = t2.r_id);
Great
insert into t1(a1) select b1 from t2 left join (select distinct t1.id from t1 ) t1 on t1.id = t2.r_id where t1.id is null;
MySQL的exists与inner join 和 not exists与 left join 性能差别惊人:
由于客户数据量越来越大,在实践中让我发现mysql的exists与inner join 和 not exists与 left join 性能差别惊人。
我们一般在做数据插入时,想插入不重复的数据,或者盘点数据在一个表,另一个表否有存在相同的数据会用not exists和exists,例如:
- insert into t1(a1) select b1 from t2 where not exists(select 1 from t1 where t1.id = t2.r_id);
如果t1的数据量很大时,性能会非常慢。经过实践,用以下方法能提高很多。
- insert into t1(a1)
- select b1 from t2
- left join (select distinct t1.id from t1 ) t1 on t1.id = t2.r_id
- where t1.id is null;
- select * from t1 where exists(select 1 from t2 where t1.id=t2.r_id);
替换为:
- select t1.* from t1
- inner join (select distinct r_id from t2) t2 on t1.id= t2.r_id
这是实践的得出的结果。不知否有其他更好的方法,或则这个只是特例而已。
补充:MySQL STRAIGHT_JOIN 与 NATURAL JOIN的使用
长话短说:straight_join实现强制多表的载入顺序,从左到右,如:
...A straight_join B on A.name = B.name
straight_join完全等同于inner join 只不过,join语法是根据“哪个表的结果集小,就以哪个表为驱动表”来决定谁先载入的,而straight_join 会强制选择其左边的表先载入。
往往我们在分析mysql处理性能时,如(Explain),如果发现mysql在载入顺序不合理的情况下,可以使用这个语句,但往往mysql能够自动的分析并处理好。
更多内容参考:
MySQL STRAIGHT_JOIN 与 NATURAL JOIN
八.参考:
相关推荐
SQL 中的左外连接、内连接、右外连接用法详解 SQL 中的连接操作是数据库管理系统中最基本的操作之一,它能够将多个表中的数据结合起来,生成一个新的结果集。本文将对 SQL 中的左外连接、内连接、右外连接进行详细...
### SQL中JOIN的使用详解 在SQL查询语言中,`JOIN`操作是非常重要的一个部分,它主要用于合并两个或多个表中的数据。通过不同的`JOIN`类型,我们可以灵活地获取所需的组合数据。本文将详细介绍五种主要的`JOIN`类型...
本篇文章将深入探讨LEFT JOIN、RIGHT JOIN以及INNER JOIN的用法,并通过实例进行对比,帮助理解它们之间的差异。 1. LEFT JOIN(左连接) LEFT JOIN返回所有左表(在本例中为A表)的记录,即使在右表(B表)中没有...
### SQL语句中JOIN的用法详解 在SQL查询语言中,`JOIN`是一个非常重要的概念,它允许我们从两个或多个表中提取数据。通过使用不同类型的JOIN操作,我们可以根据表之间的关系来灵活地组织数据。下面我们将详细介绍几...
### (Left join , Right Join, Inner Join)用法详解 #### 一、基本概念与应用场景 在数据库查询语言SQL中,连接(Join)是一种非常重要的操作,它允许我们结合两个或多个表的数据来检索信息。根据不同的连接方式,...
### SQL中的INNER JOIN详解 #### 一、INNER JOIN的基本概念 **INNER JOIN** 是SQL中最常用的连接类型之一,主要用于从两个或多个表中提取数据,其中仅返回那些满足连接条件的记录。简单来说,INNER JOIN返回的是两...
对于开发使用到数据库的应用,免不了就要使用联合查询,SQL中常用的联合查询有inner join、outer join和cross join;这三者的区别很多人都应该不是很清楚,包括我自己,下面我们一起来看看,如果你使用join连表,...
### SQL中的各种连接详解 在数据库操作中,连接(Join)是SQL语言中非常重要的一个概念,用于将多个表的数据组合在一起,以便于查询和分析。本文将详细解析Oracle数据库中常用的几种连接类型:内连接(INNER JOIN)...
### SQL语句SELECT用法详解 #### 一、概述 SQL(Structured Query Language)是一种用于管理关系数据库的标准语言。在SQL中,`SELECT`语句是最常用的操作之一,主要用于从数据库表中检索数据。通过使用不同的子句...
本资源“SQL各种查询方法详解(数据库源码加视频)”提供了一套全面的SQL查询教程,结合了数据库源码和视频教学,非常适合初学者或经验丰富的开发者用来巩固和提升SQL技能。 首先,让我们深入了解一下SQL的基本查询...
SQL中的LEFT JOIN(或LEFT OUTER JOIN)是一种联接操作,用于合并两个或多个表的数据,同时保留左表(也就是在LEFT JOIN子句中指定的表)的所有行。这个命令对于数据分析和信息检索至关重要,因为它允许你获取左表的...
### SQL连接JOIN详解 #### 一、概述 在SQL中,`JOIN`是一种非常重要的操作,用于合并两个或多个表中的数据。通过不同的`JOIN`类型,我们可以灵活地获取所需的组合数据。本文将详细介绍五种主要的`JOIN`类型:左...
### SQL Inserted 和 Deleted 表详解 在 SQL Server 中,`Inserted` 和 `Deleted` 是两个特殊的表,它们主要用于触发器(Trigger)中。当执行 INSERT、UPDATE 或 DELETE 操作时,系统会自动创建这两个虚拟表,并...
### 精彩SQL语句用法详解 #### 一、引言 SQL(Structured Query Language,结构化查询语言)是一种用于管理和处理关系型数据库的标准计算机语言。它被广泛应用于数据库查询、更新、管理和控制等方面。本文将详细...
今天,我们将使用图形来解释 SQL Join 语句的各种类型。 INNER JOIN INNER JOIN 也称为等值连接,是最基本的 Join 型。它返回两个表中满足条件的记录。例如,我们有两个表 A 和 B,我们想从这两个表中检索 name ...
这里提供的知识是基于黄玮编写的《Oracle高性能SQL引擎剖析:Oracle SQL优化与调优技术详解》一书的内容,以及上述文档提供的相关知识点。在实际应用中,可以参考这些内容来优化Oracle数据库中的SQL查询。同时,为了...
### MySQL中的JOIN详解及SQL实战 #### 一、引言 在关系型数据库管理系统(RDBMS)中,数据往往分布在多个表中。为了获取所需的信息,常常需要将这些表组合起来,这时就会用到JOIN操作。JOIN是SQL语言中非常重要的...
### SQL中的Join类型详解 在数据库操作中,`JOIN`是一种非常重要的操作,它用于将两个或多个表中的行合并到一起,以便于查询和分析跨表的数据。根据不同的连接方式,`JOIN`可以分为几种类型,包括`INNER JOIN`、`...
在《精通SQL》这本书中,作者深入浅出地讲解了SQL的基础与高级应用,涵盖了数据库理论、SQL Server的使用以及实际操作技巧。下面将根据标题和描述,详细解析SQL的一些核心知识点。 1. **数据库基础理论**: - ...