A – ( B ∩ A )
我想知道这组数学在查看时可以转化为什么,并将其与 SQL(运算符)进行比较。
如果A
和B
是相同“类型”的表(相同的列数和对应列上的兼容数据类型),则可以将其转换为 SQL,如下所示:
A EXCEPT (A INTERSECT B)
这当然等同于(在集合代数和关系代数中):
A EXCEPT B
如果A
和B
是不同“类型”的表,那么集合操作在它们之间没有意义。(连接是不同的东西,它们不应该与联合、差异或交叉点混淆,无论“解释”它们的链接有多受欢迎。)
Union、Difference 和 Intersections 也可以用多种方式表示(使用(LEFT) JOIN
, (NOT) IN
,(NOT) EXISTS
组合,除了显式的UNION
,EXCEPT
和INTERSECT
运算符)这一事实并没有改变这一点。
语法与上面不完全相同。可以使用任何一种(在 Postgres 和 SQL-Server 中工作。如果替换为 ,它也可以在 OracleEXCEPT
中工作MINUS
):
SELECT *
FROM a
EXCEPT
( SELECT *
FROM a
INTERSECT
SELECT *
FROM b
) ;
或者这个(适用于 Postgres 8.4 及更高版本:SQL-Fiddle test)
SELECT *
FROM
( TABLE a
EXCEPT
( TABLE a INTERSECT TABLE b )
) t ;
甚至这个(看马,不SELECT
!):
TABLE a
EXCEPT
( TABLE a INTERSECT TABLE b ) ;
只是在 SQL 方面给出另一种选择:
SELECT id FROM A
MINUS
SELECT id FROM B
升级版:
请注意,MINUS
从最终结果集中删除重复项并且仅存在于 Oracle 中。
SQL 标准使用其他供应商支持的 EXCEPT:
SELECT id FROM A
EXCEPT
SELECT id FROM B
在标准中,它具有DISTINCT
应该删除欺骗的选项。我想您将不得不检查特定供应商的文档,以查看是否会删除重复项。例如 SQL Server 的实现与OracleEXCEPT
中的相同MINUS
。
这计算了 A 和 B 的集合差,并且在 mats 中也等价于A - B
。所以你在这里感兴趣的是 A 中不在 B 中的元素。
您可以查看这篇博文,了解如何在 mysql 中完成设置差异。
那将是 SET A MINUS (SET A INNER JOIN SET B)。您正在获取 A 和 B (INNER JOIN) 中出现的记录,然后从 SET A (MINUS) 中删除这些记录
集合论术语中的相交等同于 SQL 术语中的 INNER JOIN。
编辑:至于你关于与 NOT IN 相同的问题,不是真的。NOT IN 是用于列值的运算符(“选择”)。MINUS、JOIN 等是集合运算符,用于在行集之间执行操作。
A – ( B ∩ A )
等价于A LEFT OUTER JOIN B WHERE TableB.id IS null
另一种选择是使用
SELECT * FROM A
WHERE
NOT EXISTS (SELECT * FROM B WHERE A.Id = B.id)