4

我确信这个问题有一个答案,但请耐心等待,因为我是 SQL 新手,不知道如何提出这个问题。

我有这样的数据(例如,这纯粹是速记)。这是在 postgres 数据库中。

table1
id    value
1     111
1     112
1     113
2     111
2     112
2     116
3     111
3     122
3     123
4     126
5     123
5     125
6     111
6     112
6     116

table2
value
111
112
116

我需要返回 table1 的 id,其中 table2 中的所有值都存在于 table1 的值中。所以对于这个例子,我的查询将返回 2 和 6。

有没有办法在 SQL 中做到这一点?或者你能指导我使用一个数据结构来让我得到这个结果吗?我可以更改任一表的结构以适应获得此结果的最终需求

非常感谢。对此的答案将是一个救生员。

4

4 回答 4

6

考虑这个演示:

CREATE TEMP TABLE table1(id int, value int);
INSERT INTO table1 VALUES
 (1,111),(1,112),(1,113)
,(2,111),(2,112),(2,116)
,(3,111),(3,122),(3,123)
,(4,126)
,(5,123),(5,125)
,(6,111),(6,112),(6,116);

CREATE TEMP TABLE table2(value int);
INSERT INTO table2 VALUES
 (111)
,(112)
,(116);

SELECT t1.id
FROM   table1 t1
JOIN   table2 t2 USING (value)
GROUP  BY t1.id
HAVING count(*) = (SELECT count(*) FROM table2)
ORDER  BY t1.id;

结果:

id
-----
2
6

返回出现的所有 id 以及一次table1提供的所有值table2
适用于两个表中的任意数量的行。

如果重复的行可以出现在table1make 中:

HAVING count(DISTINCT value) = (SELECT count(*) FROM table2) 
于 2011-12-08T02:14:37.757 回答
3

在我看来,你想知道如何提出正确的问题。这里的神奇词是“关系除法”。

它是Codd关系代数中的运算符之一,此后提出了几种变体。最近,Chris Date提议用图像关系取代整个概念。

SQL 没有明确的除法运算符。有许多使用其他运算符的解决方法,最合适的将取决于您的要求,包括精确除法或除以余数以及如何处理空除数。然后是通常的考虑:SQL产品和版本、性能、个人风格和品味等。

这里有几篇文章可以帮助您做出这些选择:

关于使关系划分变得可理解

Divided We Stand:关系除法的 SQL

于 2011-12-08T14:10:57.073 回答
1

更新另一种可能性:

SELECT t1.id
FROM (SELECT t1.id, t1.value
      FROM table1 t1
      JOIN  table2 t2 USING (value)
      GROUP BY t1.id, t1.value
      ORDER BY t1.id) t1
GROUP BY t1.id      
HAVING COUNT(*) = (SELECT COUNT(*) FROM table2)

如果您使用EXPLAIN ANALYZE,我的答案的成本始终为 893-900,即使重复行也是如此。

于 2011-12-08T12:10:57.347 回答
0

NOT EXISTS(... NOT EXISTS) 是关系除法的标准解决方案:

SELECT DISTINCT id
FROM table1 t1
WHERE NOT EXISTS (
        SELECT * FROM table2 t2
        WHERE NOT EXISTS (
                SELECT * FROM table1 t1x
                WHERE t1x.value = t2.value
                AND t1x.id = t1.id
                )
        )
        ;

在这种情况下,DISTINCT需要 s,因为我们无法访问带有s的表,只能访问引用它的联结表。idt1

于 2016-08-31T12:59:29.447 回答