乐趣区

关于sql:SQL-JOIN的常见连接方式与相关概念

JOIN 连贯操作介绍

SQL 中的连贯 JOIN 是指将来自两个或多个表、视图或物化视图的行组合在一起的查问;当查问的 FROM 子句中呈现多个表时,数据库就会执行一个连贯。查问的抉择列列表能够从这些表中抉择任何列,如果其中任意两个表存在同名的列,则必须应用表名限定整个查问中对这些列的援用以防止歧义。

大多数连贯查问至多蕴含一个连贯条件,要么在 FROM 子句中关键字 ON 前面,要么在 WHERE 子句中;连贯条件比拟来自不同表的两个列,多个条件能够用 AND 或 OR 连接起来,最终都是返回一个 bool 值;连贯条件中的列不须要也呈现在抉择列表中。蕴含连贯条件的 WHERE 子句还能够蕴含仅援用一个表的列的其余过滤条件,用于进一步限度连贯查问返回的行。

关注公众号大数据研学社:BigDataRLC,第一工夫看最新文章。

SQL 查问的根本过程

  • 单表查问:依据 WHERE 子句中的条件过滤 FROM 子句中指定表中的记录,造成两头表;如果有 GROUP BY、HAVING、WINDOW、ORDER BY、LIMIT 等子句则按程序进一步做相应解决,最初依据 SELECT 子句中的列与表达式做相应解决后返回最终后果
  • 两表连贯查问:对两表求积(笛卡尔积)并用 ON 条件和连贯类型进行过滤造成两头表;而后再依据 WHERE 条件过滤两头表的记录,最初依据 SELECT 指定的列返回查问后果
  • 多表连贯查问:先对第一个和第二个表依照两表做连贯,而后用查问后果和第三个表做连贯,以此类推,直到所有的表都连贯上为止,造成一个两头的后果表,而后依据 WHERE 条件过滤两头表的记录,最初依据 SELECT 指定的列返回查问后果

JOIN 中 ON 和 WHERE 两种条件的区别

连贯条件能够呈现在 ON 关键字或者 WHERE 子句中,然而咱们要特地留神 ON 条件和 WHERE 条件失效机会是不一样的,在大数据量状况下耗费的资源可能会存在很大的差别:

  • ON 条件:做为过滤两个连贯表的笛卡尔积造成两头表的约束条件,生成的两头表曾经是过滤后的数据
  • WHERE 条件:在有 ON 条件的两表或多表连贯中,是过滤两头表的约束条件,两头表学生成进去再做过滤

此外,INNER JOIN 中两种条件的后果是雷同的,然而用 LEFT JOIN 时(RIGHT JOIN 或 FULL JOIN 相似),因为无论 ON 的条件是否满足都会返回左表的所有记录,因而上面两个语句是不等价的:

SELECT * FROM tab1 LEFT JOIN tab2 ON (tab1.size = tab2.size) WHERE tab2.name='AAA';
SELECT * FROM tab1 LEFT JOIN tab2 ON (tab1.size = tab2.size AND tab2.name='AAA');

后面咱们提到只有是返回 bool 值表达式都能够做为 JOIN 的连贯条件,因而有人会在 ON 条件上间接写上形如 column1 != 100 的过滤条件,举荐用法是 ON 条件只进行连贯操作,WHERE 则用于过滤两头表的记录。

常见 JOIN 连贯形式

通常咱们说的 Join 的连贯形式或者说连贯类型有 5 种,最罕用的是后面 2~3 种:

  • 内连贯 INNER JOIN
  • 左外连贯 LEFT OUTER JOIN
  • 右外连贯 RIGHT OUTER JOIN
  • 全外连贯 FULL OUTER JOIN
  • 穿插连贯 CROSS JOIN

内连贯 INNER JOIN

内连贯 INNER JOIN 通常简写为 JOIN,只返回两个表中连贯字段相等的行。SQL 举例:

SELECT * 
FROM table1 JOIN table2
    ON table1.column_name1 = table2.column_name2;

下面的内连贯 SQL 还有一种等价的写法,有人称为多表联结查问:

SELECT * 
FROM table1, table2
WHERE table1.column_name1 = table2.column_name2;

左外连贯 LEFT OUTER JOIN

左外连贯 LEFT OUTER JOIN 通常简写为 LEFT JOIN,返回左表所有记录及右表中连贯字段相等的记录;以左表为准右表做匹配,匹配多个则返回多个,如右表中没有匹配,相干输入列置 NULL。SQL 举例:

SELECT *
FROM table1 LEFT JOIN table2
    ON table1.column_name1 = table2.column_name2;

右外连贯 RIGHT OUTER JOIN

右外连贯 RIGHT OUTER JOIN 通常简写为 RIGHT JOIN,返回右表所有记录及左表中连贯字段相等的记录;以右表为准左表做匹配,匹配多个则返回多个,如左表中没有匹配,相干输入列置 NULL。SQL 举例:

SELECT *
FROM table1
RIGHT JOIN table2
    ON table1.column_name1 = table2.column_name2;

全外连贯 FULL OUTER JOIN

全外连贯 FULL OUTER JOIN 通常简写为 FULL JOIN,返回包含左表和右表中的所有记录,当某行在另一个表中没有匹配行时,则另一个表的输入列置 NULL。如果表之间有匹配行,则整个后果集行蕴含基表的数据值;SQL 举例:

SELECT *
FROM table1 FULL JOIN table2
ON table1.column_name1 = table2.column_name2;

穿插连贯 CROSS JOIN

穿插连贯 CROSS JOIN,返回左表中的所有行,且左表中的每一行与右表中的所有行组合;穿插连贯也称作两个表的笛卡尔积,返回后果的行数等于两个表行数的乘积;CROSS JOIN 不带 ON 关键字,其和 INNER JOIN ON (TRUE) 等效;两个表连贯查问单没有指定连贯条件时,就会产生穿插连贯。SQL 举例:

SELECT *
FROM table1 CROSS JOIN table2;

常见 JOIN 连贯相干概念

自连贯 SELF JOIN

自连贯 SELF JOIN 是指一个表本人连贯本人,通常须要取两个不同的表别名;例如一个反对层级的分类表 category 有 3 个字段:id、name、parent_id,想要同时查问出分类 ID、分类名、父分类 ID 和父分类名就能够用自连贯:

SELECT c.id, c.name, pc.id AS parent_id, pc.name AS parent_name
FROM category AS c LEFT JOIN category AS pc 
    ON c.parent_id = pc.id

天然连贯 NATURAL JOIN

天然连贯 NATURAL JOIN 是指在两张表中寻找列名雷同的字段,而后主动地将他们连接起来,且对于列名雷同的连贯列只会返回其中一列;应用天然连贯就不能灵便指定连贯条件。例如上面两个表中存在两个雷同的字段 type 和 status,则上面两个语句等价:

SELECT * FROM table1 NATURAL JOIN table2;
SELECT * FROM table1 JOIN table2 ON table1.type = table2.type AND table1.status = table1.status;

半连贯 SEMI JOIN

半连贯 SEMI JOIN 是指在两表关联时,当第二个表中存在一个或多个匹配记录时,返回第一个表的记录。与一般 JOIN 不同,SEMI JOIN 中第一个表里的记录最多只返回一次。SEMI JOIN 通常无奈间接用 SQL 语句来示意,而是由 IN 或 EXISTS 子查问转换失去。SQL 举例:

SELECT * FROM employees WHERE dept_name IN (SELECT dept_name FROM departments)
SELECT * FROM employees WHERE EXISTS (SELECT * FROM departments WHERE employees.dept_name = departments.dept_name)

反连贯 ANTI JOIN

反连贯 ANTI JOIN 与半连贯 SEMI JOIN 相同,是指在两表关联时,当第二个表中不存在匹配记录时,返回第一个表的记录。ANTI JOIN 通常无奈间接用 SQL 语句来示意,而是由 NOT IN 或 NOT EXISTS 子查问转换失去。SQL 举例:

SELECT * FROM employees WHERE dept_name NOT IN (SELECT dept_name FROM departments)
SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM departments WHERE employees.dept_name = departments.dept_name)

显式连贯与隐式连贯

咱们在 SQL 查问语句中显示指定 JOIN 关键字的连贯通常称之为显示连贯,而不显示指定 JOIN 关键字的多表查问则能够称之为隐式连贯;例如,咱们在内连贯 INNER JOIN 里提到的 FROM 关键字前面指定多个表的写法就是隐式连贯,EXIST/NOT EXIST/IN/NOT IN 相干的用法也是隐式连贯。

等值连贯与非等值连贯

咱们在后面的例子中关键字 ON 前面的连贯条件都是形如 column1 = column2 这样的单个等值判断条件,实际上也能够是形如 column1 > column2 或 column1 != column2 甚至是 column1 < 1000 这样的一个或多个条件组成的表达式。

连贯条件都是两个表中列的相等判断组成的表达式通常称为等值连贯,否则就是非等值连贯;等值连贯是最罕用的,因为从业务应用上来说通常都是将一个表的主键在另外一个表里冗余存储(能够申明为外键也能够不申明)以示意两个表中数据记录的相关性。而非等值连贯通常容易返回不合乎业务相关性的、太多的记录。

参考资料

  • https://docs.oracle.com/en/da…
  • https://dev.mysql.com/doc/ref…
退出移动版