使用交集除外或并集关系代数的 SQL Server 查询

标签 sql sql-server relational-division

我正在尝试解决问题。如果你问我的话,这似乎是一个脑筋急转弯。

给定两个表,当第二个表中的每个记录都匹配时,仅返回第一个表中的值。因此表 1 中的记录必须与表 2 中的每条记录都匹配。如果表 2 的行数少于每一行,我想将其从最终结果中排除。

这必须在不使用 count、having、group by 的情况下完成。我必须用并集、相交、异常(exception)、存在来解决它。

顺便说一句,我正在使用 SQL Server。

CREATE TABLE table1 (id int, lid int)
INSERT INTO table1  VALUES (1, 1),(1, 2),(1,3),(1,4),(2,1),(3,3),(4,4)

CREATE TABLE table2 (lid int)
INSERT INTO table2 VALUES (1),(2),(3),(4)

表 1:

id  lid
--------
1   1
1   2
1   3
1   4
2   1
3   3
4   4

表2:

lid
-----
1
2
3
4

这里的方法“不是我应该解决的方法”。令人沮丧的是,这个解决方案非常简单,而且完全做了它应该做的事情。我无法使用 count、group by 和having。

SELECT id 
FROM dbo.table1, dbo.table2
WHERE table1.lid = table2.lid
GROUP BY id
HAVING COUNT(*) = (SELECT COUNT(*) FROM dbo.table2)

所以基本上,当表 2 中没有完整的匹配集时,我需要找到一种方法从第一个表中排除结果。在此示例中,表 1 中的唯一值与表 2 中的每个记录都匹配是 1。需要排除 2,3,4。

最佳答案

您要查找的内容有一个名称。它的名字叫relational division 。尽管可以通过多种方式对其进行模拟,但它在 SQL 中没有等效项。 Joe Celko has written one of the most complete blog posts about the topic .

由于您必须在 SQL 中使用一些更基本的关系运算符,因此这可能是您的一种解决方案:

SELECT DISTINCT id
FROM table1 t1a
WHERE NOT EXISTS (
  SELECT *
  FROM table2
  WHERE NOT EXISTS (
    SELECT *
    FROM table1 t1b
    WHERE t1a.id = t1b.id
    AND t2.lid = t1b.lid
  )
) 

它以英语非正式地阅读:

Get me all the elements in table1 for which there is no element in table2, which doesn't match such an element from table1

或者也:

Get me the elements from table1, which match all the elements in table2

关于使用交集除外或并集关系代数的 SQL Server 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46321212/

相关文章:

sql - 在一个很长的sql文件中查找第n个查询

mysql - 选择多个唯一类别 ID 的最新条目

MySQL Select ID 出现在不同的行上,一列有多个特定值

MySql关系除法内连接语法超过3个表

SQL Server 使用通配符加入并在第一次匹配时停止

mysql - 根据另一个表中的多行搜索一个表

mysql - 无法添加或更新子行 : a foreign key constraint fails: inserting using perl script

mysql - 如何确保插入 SQL View 的行将是该 View 的元素?

SQL Server 2005 : Round returns incorrect value if I use a float variable

java - 如何为 'x' 的第 n 列设置列名