47

我在尝试理解半连接的概念以及它与传统连接的不同之处时遇到了麻烦。我已经尝试了一些文章,但对解释不满意,有人可以帮我理解吗?

4

3 回答 3

51

简单的例子。让我们使用左外连接选择成绩的学生:

SELECT DISTINCT s.id
FROM  students s
      LEFT JOIN grades g ON g.student_id = s.id
WHERE g.student_id IS NOT NULL

现在与左半连接相同:

SELECT s.id
FROM  students s
WHERE EXISTS (SELECT 1 FROM grades g
              WHERE g.student_id = s.id)

后者通常更有效(取决于具体的 DBMS 和查询优化器)。

于 2017-04-10T10:43:45.140 回答
15

据我所知,支持的 SQL 方言SEMIJOIN/ANTISEMI是 U-SQL/Cloudera Impala。

半连接

半联接是 U-SQL 的一种方式,它根据行集包含在另一个行集中的行来过滤行集。其他 SQL 方言用 SELECT * FROM A WHERE A.key IN (SELECT B.key FROM B) 模式来表达这一点。

更多信息Semi Join 和 Anti Join 在 SQL 中应该有自己的语法

“半”意味着我们并没有真正加入右手边,我们只检查加入是否会为任何给定的元组产生结果。

-- IN
SELECT *
FROM Employee
WHERE DeptName IN (
  SELECT DeptName
  FROM Dept
)

-- EXISTS
SELECT *
FROM Employee
WHERE EXISTS (
  SELECT 1
  FROM Dept
  WHERE Employee.DeptName = Dept.DeptName
)

编辑:

支持 SEMI/ANTISEMI join 的另一种方言是KQL

kind=leftsemi(或 kind=rightsemi)

返回左侧与右侧匹配的所有记录。结果表仅包含左侧的列。

let t1 = datatable(key:long, value:string)  
[1, "a",  
2, "b",
3, "c"];
let t2 = datatable(key:long)
[1,3];
t1 | join kind=leftsemi (t2) on key

演示

输出:

key  value
1    a
3    c
于 2018-05-28T18:12:10.547 回答
-6

据我了解,半连接是左连接或右连接:

INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有什么区别?

因此,左(半)连接和“常规”连接之间的区别在于您只检索左表的数据(您的连接条件匹配)。而使用完全(外部)联接(我认为这就是传统联接的意思),您检索条件匹配的两个表的数据。

于 2017-04-10T09:25:04.673 回答