INNER JOIN和LEFT SEMI JOIN之间的区别

use*_*355 66 sql hive hql

INNER JOIN和之间有什么区别LEFT SEMI JOIN

在下面的场景中,为什么我得到两个不同的结果?

INNER JOIN结果集是很多大.谁能解释一下?我试图让其中的名字table_1只出现在table_2.

SELECT name
FROM table_1 a
    INNER JOIN table_2 b ON a.name=b.name

SELECT name
FROM table_1 a
    LEFT SEMI JOIN table_2 b ON (a.name=b.name)
Run Code Online (Sandbox Code Playgroud)

D S*_*ley 102

一个INNER JOIN返回两个表中的列.A LEFT SEMI JOIN只返回左侧表中的记录.它相当于(在标准SQL中):

SELECT name
FROM table_1 a
WHERE EXISTS(
    SELECT * FROM table_2 b WHERE (a.name=b.name))
Run Code Online (Sandbox Code Playgroud)

如果右侧列中有多个匹配的行,则INNER JOIN每个匹配列将返回一行,而LEFT SEMI JOIN只返回左表中的行.这就是为什么你在结果中看到不同数量的行.

我试图获取table_1中只出现在table_2中的名称.

然后a LEFT SEMI JOIN是要使用的适当查询.

  • 很好的答案正是我想要的。我会更准确地表达答案:“...INNER JOIN 将为右表的每个匹配**行返回一行,而 LEFT SEMI JOIN... (2认同)
  • 与此相反的是LEFT ANTI JOIN,它根据一个键将左表中右表的数据过滤掉。我以为我会把这个金块留在这里给可能正在寻找的人! (2认同)

小智 38

假设有2个表TableA和TableB只有2列(Id,Data)和以下数据:

表A:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataA11 |
|  1 | DataA12 |
|  1 | DataA13 |
|  2 | DataA21 |
|  3 | DataA31 |
+----+---------+
Run Code Online (Sandbox Code Playgroud)

表B:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataB11 |
|  2 | DataB21 |
|  2 | DataB22 |
|  2 | DataB23 |
|  4 | DataB41 |
+----+---------+
Run Code Online (Sandbox Code Playgroud)

Inner Join on列Id将返回两个表中的列以及仅匹配的记录:

.----.---------.----.---------.
| Id |  Data   | Id |  Data   |
:----+---------+----+---------:
|  1 | DataA11 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA12 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA13 |  1 | DataB11 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB21 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB22 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB23 |
'----'---------'----'---------'
Run Code Online (Sandbox Code Playgroud)

列上的左连接(或左外连接)Id将返回两个表中的列和匹配记录与左表中的记录(右表中的空值):

.----.---------.----.---------.
| Id |  Data   | Id |  Data   |
:----+---------+----+---------:
|  1 | DataA11 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA12 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA13 |  1 | DataB11 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB21 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB22 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB23 |
:----+---------+----+---------:
|  3 | DataA31 |    |         |
'----'---------'----'---------'
Run Code Online (Sandbox Code Playgroud)

列上的右连接(或右外连接)Id将返回来自两个表的列和匹配记录以及右表中的记录(左表中的空值):

???????????????????????????????
? Id ?  Data   ? Id ?  Data   ?
???????????????????????????????
?  1 ? DataA11 ?  1 ? DataB11 ?
?  1 ? DataA12 ?  1 ? DataB11 ?
?  1 ? DataA13 ?  1 ? DataB11 ?
?  2 ? DataA21 ?  2 ? DataB21 ?
?  2 ? DataA21 ?  2 ? DataB22 ?
?  2 ? DataA21 ?  2 ? DataB23 ?
?    ?         ?  4 ? DataB41 ?
???????????????????????????????
Run Code Online (Sandbox Code Playgroud)

列上的完全外部联接Id将返回来自两个表的列以及来自左表的记录的匹配记录(右表中的空值)和右表中的记录(左表中的空值):

???????????????????????????????
? Id ?  Data   ? Id ?  Data   ?
???????????????????????????????
?  - ?         ?    ?         ?
?  1 ? DataA11 ?  1 ? DataB11 ?
?  1 ? DataA12 ?  1 ? DataB11 ?
?  1 ? DataA13 ?  1 ? DataB11 ?
?  2 ? DataA21 ?  2 ? DataB21 ?
?  2 ? DataA21 ?  2 ? DataB22 ?
?  2 ? DataA21 ?  2 ? DataB23 ?
?  3 ? DataA31 ?    ?         ?
?    ?         ?  4 ? DataB41 ?
???????????????????????????????
Run Code Online (Sandbox Code Playgroud)

左半连接Id将仅返回左表中的列,仅从左表中匹配记录:

????????????????
? Id ?  Data   ?
????????????????
?  1 ? DataA11 ?
?  1 ? DataA12 ?
?  1 ? DataA13 ?
?  2 ? DataA21 ?
????????????????
Run Code Online (Sandbox Code Playgroud)

  • Distinct 听起来不安全,假设 A 包含两个相同的记录。 (5认同)
  • 我曾经称之为“LEFT INNER Join”。 (3认同)

Kum*_*mar 31

在Hive中尝试并获得以下输出

表格1

1,WQE,奈,印度

2,STU,撒冷,印度

3,MIA,印度班加罗尔

4,yepie,纽约,美国

表2

1,WQE,奈,印度

2,STU,撒冷,印度

3,MIA,印度班加罗尔

5,chapie,Los angels,USA

内部联接

SELECT*FROM table1 INNER JOIN table2 ON(table1.id = table2.id);

1 wqe chennai india 1 wqe chennai india

2 stu salem india 2 stu salem india

3 mia bangalore india 3 mia bangalore india

左加入

SELECT*FROM table1 LEFT JOIN table2 ON(table1.id = table2.id);

1 wqe chennai india 1 wqe chennai india

2 stu salem india 2 stu salem india

3 mia bangalore india 3 mia bangalore india

4 yepie newyork USA NULL NULL NULL NULL

左半连接

SELECT*FROM table1 LEFT SEMI JOIN table2 ON(table1.id = table2.id);

1 wqe chennai india

2 stu salem india

3 mia bangalore印度

注意:仅显示左表中的记录,而对于左连接,则显示两个表记录

  • 你确实应该在 RHS 表中放入一些重复的 id 来查看完整的差异 - 例如,如果表 2 中有两个 id 为 1 的值,则使用 INNER JOIN 时你将在结果中得到 2 行,而使用 LEFT SEMI 时只有 1 行加入。这表明您可以获得不同数量的返回行,以及仅使用 LSJ 从 LHS 表中获取列 (2认同)