INNER JOIN和LEFT SEMI JOIN之间的区别

时间:2014-02-12 20:21:47

标签: sql hql hive

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)

4 个答案:

答案 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 中有匹配项。