【问题标题】:Is left join commutative? What are its properties?左连接是可交换的吗?它的属性是什么?
【发布时间】:2014-04-14 19:21:27
【问题描述】:

假设表TableATableBTableCTableD

是以下查询:

TableA INNER JOIN TableB LEFT JOIN TableC LEFT JOIN TableD

(全部连接到一个 id 列)相当于:

TableA INNER JOIN TableB
     INNER JOIN TableC
     LEFT JOIN TableD    

UNION  

TableA INNER JOIN TableB
    LEFT JOIN TableC ON TableB.c_id IS NULL
    LEFT JOIN TableD    

?

注意:
或者代替 union 只是做

TableA INNER JOIN TableB
       INNER JOIN TableC
        LEFT JOIN TableD  

然后

TableA INNER JOIN TableB
       LEFT JOIN TableC ON TableB.c_id IS NULL
       LEFT JOIN TableD    

然后合并结果

更新

(A INNER JOIN B) LEFT JOIN C LEFT JOIN D 

同:

A INNER JOIN (B LEFT JOIN C) LEFT JOIN D

?

【问题讨论】:

  • 你为什么把它命名为commutative
  • LEFT JOIN 表示它(至少)保留左侧表格中的每一行,所以不,它不是“可交换的”跨度>
  • 我在提供的示例中看不到订单更改。如果您的问题是TableA LEFT JOIN TableB <=> TableB LEFT JOIN TableA,答案是否定的。
  • 当您提出问题时,您的脑海中有一些背景,但它只是在您的脑海中。
  • @Jim 。 . .查询的语义(它的作用)由from 子句中的表的顺序以及用于连接它们的连接类型决定。 SQL 优化器可能会选择不同的执行顺序,但给定查询的结果是根据 SQL 语句很好地定义的。

标签: mysql sql join left-join relational-algebra


【解决方案1】:

维基百科:

“在数学中,如果改变操作数的顺序不会改变结果,则二元运算是可交换的。它是许多二元运算的基本属性,许多数学证明都依赖于它。”

答案:

不,左连接不是可交换的。内连接是。

但这并不是你真正要问的。

是以下查询:

TableA INNER JOIN TableB LEFT JOIN TableC LEFT JOIN TableD

(全部连接到一个 id 列)相当于:

TableA INNER JOIN TableB
       INNER JOIN TableC
        LEFT JOIN TableD   
UNION     
TableA INNER JOIN TableB
        LEFT JOIN TableC ON TableB.c_id IS NULL
        LEFT JOIN TableD    

答案:

也没有。一般来说,联合和连接并不能真正完成同样的事情。在某些情况下,您可能可以等效地编写它们,但我认为您所展示的伪 sql 并不那么通用。 ON 宪法似乎不应该起作用(也许我在 MySQL 中不知道的一些东西?)

这是我认为等效的一组简化查询。

SELECT * 
  FROM TableA a 
       LEFT JOIN 
       TableB b ON a.id = b.id_a 

SELECT * 
  FROM TableA a 
       INNER JOIN 
       TableB b ON a.id = b.id_a 
UNION      
SELECT * 
  FROM TableA a  
       LEFT JOIN 
       TableB b ON a.id = b.id_a 
 WHERE TableB.id IS NULL

编辑 2:

这是另一个更接近您但本质相同的示例。

SELECT * 
  FROM            TableA a 
       INNER JOIN TableB b ON a.id = b.id_a 
        LEFT JOIN TableC c ON b.id = c.id_b 

相同
SELECT * 
  FROM TableA a 
       INNER JOIN TableB b ON a.id = b.id_a 
       INNER JOIN TableC c ON b.id = c.id_b 
UNION      
SELECT * 
  FROM TableA a  
       INNER JOIN TableB b ON a.id = b.id_a 
        LEFT JOIN TableC c ON b.id = c.id_b 
 WHERE TableC.id IS NULL

但我仍然不认为我在回答你真正的问题。

【讨论】:

  • Karl,你能概括一下为什么你认为它们不相等吗?由于我在评论中概述的原因,我认为它们是。
  • 那么TableA INNER JOIN TableB INNER JOIN TableC LEFT JOIN TableDTableA INNER JOIN TableB LEFT JOIN TableC ON TableB.c_id IS NULL LEFT JOIN TableD的结果组合和原来的查询不是同一个结果集?
  • 您的查询中的TableCTableD 在哪里?左连接在 TableC 而不是 TableB
  • 我认为不会。就像我的更新说的那样,我想如果你把它从那里移到那里。不过,证明在布丁中,所以在 sqlfiddle.com 上放一个演示,看看它是否有效。当然,我可能对示例中不完整的 sql 感到困惑。
  • Jim,我在示例中进行了简化。额外的表无关紧要。
猜你喜欢
  • 2015-08-08
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多