什么是半连接数据库?

Dar*_*dow 18 sql database join

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

Iur*_*Ant 21

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

SELECT DISTINCT s.id
FROM  students s
      LEFT JOIN grades g ON g.student_id = s.id
WHERE g.student_id IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

现在与左半连接相同:

SELECT s.id
FROM  students s
WHERE EXISTS (SELECT 1 FROM grades g
              WHERE g.student_id = s.id)
Run Code Online (Sandbox Code Playgroud)

后者效率更高.

  • `x left join y on c where ya is not null` 是 `x inside join y on c`。在第一个查询中,左连接是不需要的且具有误导性。“更有效率”错误。取决于DBMS优化器/实现,优化很简单。 (10认同)
  • @BrentB 必须选择某些东西,但不需要实际数据(一个体面的优化器应该能够优化掉任何像“SELECT *”这样的替代方案,因此它更多的是强化人类同行的意图,即不使用数据) (4认同)
  • 为什么在“WHERE EXISTS”语句的第一部分中总是显示“SELECT 1”? (3认同)
  • @JamesWierzba 查询优化器可能会认识到它们是相同的,并使用相同的查询计划来运行任一查询。但是,从概念上讲,在第一个查询中,您将首先找到每个学生的所有成绩,然后删除任何没有成绩的学生,然后删除重复的学生,直到留下唯一的学生。在第二个查询中,您逐个学生检查该学生是否至少有一个成绩。因此无需在最后枚举所有成绩或删除重复的学生 ID。同样,优化器可能足够聪明,可以对两者使用相同的算法 (3认同)

Luk*_*zda 9

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

SEMIJOIN

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

更多信息半联接和反联接在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
)
Run Code Online (Sandbox Code Playgroud)

编辑:

支持SEMI / ANTISEMI连接的另一种方言是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
Run Code Online (Sandbox Code Playgroud)

演示

输出:

key  value
1    a
3    c
Run Code Online (Sandbox Code Playgroud)