【问题标题】:Querying for rows with no foreign key (NOT NULL Foreign key) pointing to them查询没有指向它们的外键(NOT NULL Foreign key)的行
【发布时间】:2015-04-30 15:47:25
【问题描述】:

我已经阅读了几篇描述与我非常相似的问题的帖子,但我还没有能够解决我的问题。就是这样:

有表 A、B、C 和 D。表 D 被其他 3 个表引用,只有表 (A) 有一个“可为空”外键,我需要找到 D 中不是的行被其他 3 个表中的任何一个指向/引用。到目前为止,我已经能够过滤所有行,包括我想用这段代码找到的行:

SELECT D.Id as Id, A.Id as A_Id, B.Id as B_Id, C.Id as C_Id
FROM D
LEFT OUTER JOIN A --this is the nullable one
ON D.Id = A.D_Id
LEFT OUTER JOIN B
ON D.Id = B.D_Id
LEFT OUTER JOIN C
ON D.Id = C.D_Id

虽然我可以通过查看结果在结果中看到我需要的行,并且如果我尝试按 IS NULL 过滤,它们将外键字段显示为空,但我根本没有得到任何结果,这是我使用的查询:

SELECT D.Id as Id, A.Id as A_Id, B.Id as B_Id, C.Id as C_Id
FROM D
LEFT OUTER JOIN A --this is the nullable one
ON D.Id = A.D_Id
LEFT OUTER JOIN B
ON D.Id = B.D_Id
LEFT OUTER JOIN C
ON D.Id = C.D_Id
WHERE A.D_Id IS NULL AND B.D_Id IS NULL AND C.D_Id IS NULL

任何帮助将不胜感激。 提前致谢

编辑

我已经尝试过了,虽然它是一种非常不同的方法,但它确实有效:

SELECT *
FROM D
WHERE     Id not in (Select D_Id from A) 
      and Id not in (Select D_Id from B) 
      and Id not in (Select D_Id from C) 

【问题讨论】:

  • 您的第二个查询看起来正确...
  • @Blim 他的第二个查询在技术上应该可以正常工作,就像您放在那里的数据一样。我想如果没有完整的表结构和他的数据看起来,这使得这更难弄清楚。
  • 是的,它几乎是正确的。看看我的回答你好应该检查一个不可为空的列,如 A.Id、B.Id、C.Id。

标签: sql sql-server sql-server-2008


【解决方案1】:

第二个查询几乎正确!

替代

WHERE A.D_Id IS NULL AND B.D_Id IS NULL AND C.D_Id IS NULL

我会用

WHERE A.Id IS NULL AND B.Id IS NULL AND C.Id IS NULL

SELECT D.Id as Id, A.Id as A_Id, B.Id as B_Id, C.Id as C_Id
FROM D
   LEFT OUTER JOIN A --this is the nullable one
      ON D.Id = A.D_Id
   LEFT OUTER JOIN B
      ON D.Id = B.D_Id
   LEFT OUTER JOIN C
      ON D.Id = C.D_Id
WHERE A.Id IS NULL AND B.Id IS NULL AND C.Id IS NULL

Sql Fiddle Updated

【讨论】:

  • 这行得通,虽然我不知道为什么会这样,你能解释一下吗@Blim
  • @Luiso 您的查询也是正确的!你确定你在真正的问题中做同样的事情吗?您是否根据您在 ON 子句中使用的列过滤掉行?
  • 是的@Blim,我试了几次,每次都得到相同的空响应。我不明白为什么你的工作虽然
  • @Luiso 我不明白为什么你的不是你在更新的小提琴中看到的两个查询都有效!
【解决方案2】:

您是否尝试过使用 OR 而不是 AND 来获得您想要的结果?可能是其中一个表的连接中为空,而另一个表中的连接不为空。

SELECT D.Id as Id, A.Id as A_Id, B.Id as B_Id, C.Id as C_Id
FROM D
LEFT OUTER JOIN A --this is the nullable one
ON D.Id = A.D_Id
LEFT OUTER JOIN B
ON D.Id = B.D_Id
LEFT OUTER JOIN C
ON D.Id = C.D_Id
WHERE A.D_Id IS NULL OR B.D_Id IS NULL OR C.D_Id IS NULL

编辑:这会给你想要的结果吗?

SELECT *
FROM D
WHERE D.id NOT IN (SELECT D_id FROM A)
AND D.id NOT IN (SELECT D_id FROM B)
AND D.id NOT IN (SELECT D_id FROM C)

【讨论】:

  • 对不起@SLin,但 OR 对我不起作用,我只想要没有外键指向它们的行,在这段代码中,我将得到至少一个外键不指向的行他们非常感谢您的快速响应
  • @Luiso Strange,这在技术上应该可以工作,你能试试第二个查询,看看它是否能给你正确的结果吗?
【解决方案3】:

您是否尝试过使用 NOT EXISTS 来排除其他表引用的表 D 条目?

SELECT 
    D.Id as Id
FROM 
    D
WHERE
    NOT EXISTS( SELECT 1 FROM A WHERE D.Id = A.D_Id)
    AND NOT EXISTS( SELECT 1 FROM B WHERE D.Id = B.D_Id)
    AND NOT EXISTS( SELECT 1 FROM C WHERE  D.Id = C.D_Id);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-09
    • 2016-07-12
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 2014-11-10
    相关资源
    最近更新 更多