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)
答案 0 :(得分:87)
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_1中仅出现在table_2中的名称。
然后LEFT SEMI JOIN
是要使用的适当查询。
答案 1 :(得分:25)
在Hive中尝试并获得以下输出
表1
1,wqe,chennai,india
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 india
注意:仅显示左表中的记录,而对于Left Join,显示的表记录
答案 2 :(得分:22)
假设有2个表TableA和TableB只有2列(Id,Data)和以下数据:
<强>表A:强>
+----+---------+
| Id | Data |
+----+---------+
| 1 | DataA11 |
| 1 | DataA12 |
| 1 | DataA13 |
| 2 | DataA21 |
| 3 | DataA31 |
+----+---------+
<强>表B:强>
+----+---------+
| Id | Data |
+----+---------+
| 1 | DataB11 |
| 2 | DataB21 |
| 2 | DataB22 |
| 2 | DataB23 |
| 4 | DataB41 |
+----+---------+
列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 |
'----'---------'----'---------'
列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 | | |
'----'---------'----'---------'
列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 │
└────┴─────────┴────┴─────────┘
列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 ║
╚════╩═════════╩════╩═════════╝
列Id
上的左半连接将仅返回左表中的列,仅从左表中匹配记录:
┌────┬─────────┐
│ Id │ Data │
├────┼─────────┤
│ 1 │ DataA11 │
│ 1 │ DataA12 │
│ 1 │ DataA13 │
│ 2 │ DataA21 │
└────┴─────────┘
答案 3 :(得分:0)
以上所有答案都是正确的。然而,在实践中,在想象 LEFT SEMI JOIN 时,它有助于关联 filter
的心智模型。
答案是 LEFT 表中行的子集,这些行在 RIGHT TABLE 中有匹配项。