怎么理解数据库中not exist?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么理解数据库中not exist?相关的知识,希望对你有一定的参考价值。

谁能帮我解释一下,说得浅显一点,看不懂最内层嵌套什么意思

参考技术A not exists 是取反逻辑,也就是里面查询没有结果集就是为真,如果有结果集就是为假。然后作为整体的条件拼接到著查询上

相关子查询中的 EXISTS 和 NOT EXISTS

【中文标题】相关子查询中的 EXISTS 和 NOT EXISTS【英文标题】:EXISTS and NOT EXISTS in a correlated subquery 【发布时间】:2014-06-26 15:17:35 【问题描述】:

大约一天以来,我一直在努力研究如何进行特定查询,现在已经到了需要一些外部帮助的地步。因此我的问题。

给定以下数据;

DECLARE @Data AS TABLE
(
      OrgId INT,
      ThingId INT
)

DECLARE @ReplacementData AS TABLE
(
      OldThingId INT,
      NewThingId INT
)

INSERT INTO @Data (OrgId, ThingId)
VALUES (1, 2), (1, 3), (1, 4),
       (2, 1), (2, 4),
       (3, 3), (3, 4)

INSERT INTO @ReplacementData (OldThingId, NewThingId)
VALUES (3, 4), (2, 5)

我想查找任何具有已替换的“事物”的组织,如@ReplacementData 表变量中所示。我想查看 org id,他们拥有的东西已经被替换,以及应该替换它的东西的 id。所以例如给定上面的数据,我应该看到;

Org id, Thing Id, Replacement Thing Id org doesn't have but should have 
1, 2, 5 -- As Org 1 has 2, but not 5

我已经尝试过很多次尝试让这个工作正常进行,但我似乎无法弄清楚如何去做。以下是我的一些尝试,但我认为我还差得很远;

-- Attempt using correlated subqueries and EXISTS clauses
-- Show all orgs that have the old thing, but not the new thing
-- Ideally, limit results to OrgId, OldThingId and the NewThingId that they should now have too
SELECT *
  FROM @Data d
 WHERE EXISTS (SELECT *
                 FROM @Data oldstuff
                WHERE oldstuff.OrgId = d.OrgId
                  AND oldstuff.ThingId IN
                (SELECT OldThingID
                   FROM @ReplacementData))
   AND NOT EXISTS (SELECT *
                 FROM @Data oldstuff
                WHERE oldstuff.OrgId = d.OrgId
                  AND oldstuff.ThingId IN
                (SELECT NewThingID
                   FROM @ReplacementData))


   -- Attempt at using a JOIN to only include those old things that the org has (via the where clause)
   -- Also try exists to show missing new things. 
   SELECT *
      FROM @Data d
 LEFT JOIN @ReplacementData rd ON rd.OldThingId = d.ThingId
     WHERE NOT EXISTS (
            SELECT *
              FROM @Data dta
        INNER JOIN @ReplacementData rep ON rep.NewThingId = dta.ThingId
             WHERE dta.OrgId = d.OrgId
    )
   AND rd.OldThingId IS NOT NULL

非常感谢您对此的任何帮助。我很可能完全错了,所以如果有更好的方法来解决这类问题,请告诉我。

【问题讨论】:

我不是 100% 清楚这里的要求。能详细说明一下规则吗? “我想查看 org id,他们拥有的东西已经被替换,以及应该替换它的东西的 id”对我来说并不清楚。我得到了 1,2,5 - 但为什么不是 1,3,4 和 3,3,4??? 不是 1、3、4,因为组织 1 有事物 3 和 4。与组织 3 相同。它同时具有 3 和 4。我想找到有旧事物但还不是新事物的组织. 知道了...答案来了。 【参考方案1】:

试试这个并告诉我。

DECLARE @Data AS TABLE
(
      OrgId INT,
      ThingId INT
)

DECLARE @ReplacementData AS TABLE
(
      OldThingId INT,
      NewThingId INT
)

INSERT INTO @Data (OrgId, ThingId)
VALUES (1, 2), (1, 3), (1, 4),
       (2, 1), (2, 4),
       (3, 3), (3, 4)

INSERT INTO @ReplacementData (OldThingId, NewThingId)
VALUES (3, 4), (2, 5)

SELECT D.OrgId, RD.*
FROM @Data D 
JOIN @ReplacementData RD
   ON D.ThingId=RD.OldThingId
   LEFT OUTER JOIN @Data EXCLUDE
      ON D.OrgId = EXCLUDE.OrgId
      AND RD.NewThingId = EXCLUDE.ThingId
WHERE EXCLUDE.OrgId IS NULL

【讨论】:

这当然看起来很有希望。明天上班时我会试一试,然后告诉你我的进展如何。非常感谢。 我终于回来测试了它,它很有效。我从不倾向于使用自连接,我认为这是我在这个拼图中缺失的一块。我太忙于围绕如何描述问题来构建我的查询(即,向我展示所有拥有旧事物(存在)但没有新事物(不存在)的组织)。你的方法更好。再次感谢。

以上是关于怎么理解数据库中not exist?的主要内容,如果未能解决你的问题,请参考以下文章

新手求助:最好简单明了点,sql中exist 和 not exist 的区分如何理解他们??

mysql中not exists的简单理解

sqlite怎么判断表里面是不是有数据。not exists

为啥 SQL 中无法避免双重嵌套的 NOT EXISTS 语句

数据库语言 not exists 是啥意思?

为什么 EXISTS(NOT EXIST) 与 JOIN(LEFT JOIN) 的性能会比 IN(NOT IN) 好