Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL选择存在子集的所有行_Sql_Database_Postgresql_Relational Division - Fatal编程技术网

SQL选择存在子集的所有行

SQL选择存在子集的所有行,sql,database,postgresql,relational-division,Sql,Database,Postgresql,Relational Division,我确信这个问题有一个答案,但请容忍我,因为我是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 val

我确信这个问题有一个答案,但请容忍我,因为我是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中有什么方法可以做到这一点吗?或者你能给我一个数据结构,让我得到这个结果吗?我能够改变任何一个表的结构,以适应最终获得这个结果的需要

非常感谢你。解决这个问题的办法就是救命。

考虑一下这个演示:

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
返回
table1
的所有ID,这些ID与
table2
提供的所有值一起出现一次。
适用于两个表中任意数量的行

如果重复行出现在
表1
中,请执行以下操作:

HAVING count(DISTINCT value) = (SELECT count(*) FROM table2) 

更新另一种可能性:

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 ANALYSE,我的答案的成本始终是893-900,即使是重复的行。

在我看来,你想知道如何提出正确的问题,也需要付出同样多的代价。这里的神奇词语是“关系划分”

它是世纪年代的运营商之一,自那时以来,已经提出了几项变更。最近,有人提议将整个概念替换为

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

以下几篇文章可以帮助您做出以下选择:

不存在(…不存在)是关系划分的标准解决方案:

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
,因为我们无法访问具有
id
s的域表,只能访问引用它的连接表
t1

在我看来@ErwinBrandstetter的答案已经是“拯救你的生命”。您是否介意接受它作为正确答案,或者对此答案的任何问题进行评论。请用各种方法查看此问题以解决此关系划分问题:此查询的成本可能低于Erwin的,但它不是正确的解决方案。如果OP的示例中有一行
(7111)
,那么输出将包含
id
7
,即使没有
(7112)
(7116)
行。你没想过要提到吗?@某天当:你是对的,它是密切相关的。相比之下,这个例子有点简化了。+1在关系划分的主题上是非常有用的切入点。