内连接与左半连接的区别

INNER JOINLEFT 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)
165953 次浏览

INNER JOIN可以从两个表中的列返回数据,并且可以复制任何一边有多个匹配的记录值。LEFT SEMI JOIN只能返回左边表中的列,并从右边表中有一个或多个匹配项的左边表中生成每个记录中的一个(与匹配项的数量无关)。它相当于(在标准 SQL 中) :

SELECT name
FROM table_1 a
WHERE EXISTS(
SELECT * FROM table_2 b WHERE (a.name=b.name))

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

我尝试获取只出现在 table _ 2中的 table _ 1中的名称。

那么 LEFT SEMI JOIN就是要使用的适当查询。

Tried in Hive and got the below output

表1

1,WQE,chennai,India 印度

斯图,塞勒姆,印度

3米亚,班加罗尔,印度

4,yepie,newyork,USA

表2

1,WQE,chennai,India 印度

斯图,塞勒姆,印度

3米亚,班加罗尔,印度

美国洛杉矶天使队5分

内部连接

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

印度,印度

2 Stu Salem India 2 Stu Salem India

3我的班加罗尔印度3我的班加罗尔印度

Left Join

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

印度,印度

2 Stu Salem India 2 Stu Salem India

3我的班加罗尔印度3我的班加罗尔印度

4 yepie newyork USA NULL NULL NULL NULL

左半连接

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

印度

2 Stu Salem India

3 Mia Bangalore India

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

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

表 A:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataA11 |
|  1 | DataA12 |
|  1 | DataA13 |
|  2 | DataA21 |
|  3 | DataA31 |
+----+---------+

TableB:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataB11 |
|  2 | DataB21 |
|  2 | DataB22 |
|  2 | DataB23 |
|  4 | DataB41 |
+----+---------+

Id列上的 Inside Join 将返回表中的列,并且只返回匹配的记录:

.----.---------.----.---------.
| 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 |
'----'---------'----'---------'

Left Join (or Left Outer join) on column Id will return columns from both the tables and matching records with records from left table (Null values from right table):

.----.---------.----.---------.
| 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 |    |         |
'----'---------'----'---------'

Id上的 Right Join (或 Right Foreign Join)将返回两个表中的列,并将记录与右表中的记录匹配(左表中的 Null 值) :

┌────┬─────────┬────┬─────────┐
│ 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 │
└────┴─────────┴────┴─────────┘

Id列上的 Full Foreign Join 将返回两个表中的列,并将记录与左表中的记录(右表中的 Null 值)和右表中的记录(左表中的 Null 值)匹配:

╔════╦═════════╦════╦═════════╗
║ 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 ║
╚════╩═════════╩════╩═════════╝

在列 Id上的 Left half Join 将只从左表返回列,并且只从左表返回匹配的记录:

┌────┬─────────┐
│ Id │  Data   │
├────┼─────────┤
│  1 │ DataA11 │
│  1 │ DataA12 │
│  1 │ DataA13 │
│  2 │ DataA21 │
└────┴─────────┘

以上答案全部正确。然而在实践中,它有助于联想心理模型的 filter想象左半球连接。

答案是来自 LEFT 表的行的子集,它们在 RightTABLE 中具有匹配项。

半连接 LeftRight给你的行,将一直保持在 Left,如果你将加入与 Right

Left table:
KEY:  1, 2, 3
VAL1: a, b, c


Right table:
KEY:  2, 3, 4
VAL2: d, e, f


# Semi join:
KEY:  2, 3
VAL1: b, c


# Actual inner join
KEY:  2, 3
VAL1: b, c
VAL2: d, e