Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.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
Mysql如何从集合中排除子集?_Mysql_Sql_Select_Set - Fatal编程技术网

Mysql如何从集合中排除子集?

Mysql如何从集合中排除子集?,mysql,sql,select,set,Mysql,Sql,Select,Set,我有一个如下所示的虚拟表,显示谁拥有食物空值表示食物为普通食物。我在想一个问题,问主人拥有什么食物。假设所有者A,输出将是下面的输出。如果所有者也拥有通常拥有的东西,则输出将只打印“2”,而不是“1”和“2”。我尝试了使用not exist的查询,但仍然无法通过逻辑。我怎样才能达到我想要的逻辑?谢谢 Table t: ID OWNER FOOD 1 null rice 2 A rice 3 B apple 4 null oran

我有一个如下所示的虚拟表,显示谁拥有食物<代码>空值表示食物为普通食物。我在想一个问题,问主人拥有什么食物。假设所有者A,输出将是下面的输出。如果所有者也拥有通常拥有的东西,则输出将只打印“2”,而不是“1”和“2”。我尝试了使用
not exist
的查询,但仍然无法通过逻辑。我怎样才能达到我想要的逻辑?谢谢

Table t:
ID   OWNER   FOOD
1    null    rice
2    A       rice
3    B       apple
4    null    orange

Output:
ID   OWNER   FOOD
2    A       rice
4    null    orange

Tried query:
SELECT *
FROM table t
WHERE t.OWNER= 'A'
AND NOT EXISTS (    ....
                )

您可以尝试使用以下逻辑:

SELECT *
FROM yourTable t1
WHERE
    OWNER = 'A' OR
    (OWNER IS NULL AND NOT EXISTS (SELECT 1 FROM yourTable t2
                                   WHERE t2.FOOD = t1.FOOD AND t2.OWNER = 'A'));

这里的逻辑是保留所有者为
A
的任何记录,或者保留所有者为空的任何记录,前提是我们尚未包含与该空记录具有相同食物的
A
记录

编辑:

如果需要更快地运行上述查询,可以通过添加以下复合索引对其进行优化:

CREATE INDEX idx ON yourTable (OWNER, FOOD);

这将加速外部查询中的
WHERE
子句,并加速exists查找。

您可以尝试使用此exists逻辑:

SELECT *
FROM yourTable t1
WHERE
    OWNER = 'A' OR
    (OWNER IS NULL AND NOT EXISTS (SELECT 1 FROM yourTable t2
                                   WHERE t2.FOOD = t1.FOOD AND t2.OWNER = 'A'));

这里的逻辑是保留所有者为
A
的任何记录,或者保留所有者为空的任何记录,前提是我们尚未包含与该空记录具有相同食物的
A
记录

编辑:

如果需要更快地运行上述查询,可以通过添加以下复合索引对其进行优化:

CREATE INDEX idx ON yourTable (OWNER, FOOD);

这将加快外部查询中的
WHERE
子句的速度,以及加快exists查找的速度。

请问您为什么使用“select 1”而不是“select*”?没有理由,两种方法都可以。在某些数据库上,使用
SELECT 1
优于
SELECT*
。有没有更快的方法来实现此逻辑?我发现notexist需要很长时间才能完成,当数据被删除时bulk@WILLIAM添加一个索引,q.v.我在上面更新的答案。我可以问一下为什么您使用“选择1”而不是“选择*”?没有理由,两者都可以。在某些数据库上,使用
SELECT 1
优于
SELECT*
。有没有更快的方法来实现此逻辑?我发现notexist需要很长时间才能完成,当数据被删除时bulk@WILLIAM在上面添加一个索引,q.v.我的更新答案。