【问题标题】:How to deal with duplicate keys如何处理重复键
【发布时间】:2018-12-05 19:22:32
【问题描述】:

tblA

身份证

tblB

id, id2

我想检查 tbl A ID 是否存在于 tbl B ID 但不查看 id2, tblB 中的 id2 列将具有 tblA 中存在的键。

SELECT id
FROM tblA as a
WHERE NOT EXISTS 
(
SELECT * FROM tblB AS b
WHERE a.id = b.id
)

从逻辑上讲,这应该可行,但由于某种原因,它还为我提供了 tblB 中 id2 列中存在的值,而 tblA id 中不存在这些值

样本数据

tblA

ID 
1
2 
3
4 

tblB

tblb_ID   | ID2 
3         | 34
4         | 38 
12        | 93
43        | 54
54        | 4

预期结果

1,2 因为 1 和 2 在 tblB 中不存在。

我得到了什么,

只有1,因为ID2中存在4,这是为什么呢?

【问题讨论】:

  • 拜托,如果您可以添加一些示例数据和预期结果,这将有助于澄清您的问题。
  • 您确定吗,您从查询中只得到id: 1,请检查:db-fiddle.com/f/aY6kwu1VVnj6m6u6FmanzX/0。它给了我 ID 12。也许您的样本集与您的解释不一致?
  • 我同意 D. Smania 的评论——即使它与我在函数中提供的解决方案相似,您的代码也应该可以工作。其他东西必须解释您的结果,因为您的 EXISTS 查询应该可以工作。
  • @Will Driver 的 ID 号为 22 在您的查询结果中,因为表 MoSpo_RaceEntry 的列 raceEntryDriverId 上没有任何 ID 号 22。 ID 号 22 仅出现在该表的 raceEntryCarId 列中,与汽车有关,与司机无关。
  • @我会发疯吗,大声笑,如果您检查:ID 号22 不在raceEntryDriverId 列上,这就是它出现在您的查询中的原因。难道你不想要这个:我只想要所有不在raceEntryDriverId中的司机

标签: mysql sql


【解决方案1】:

如果我理解您的问题,应该很简单。您只需要 tblA 中 tblA.id 与 tblB.id 不匹配的行。 tblB.id2 没关系。

 SELECT * FROM tblA WHERE id NOT IN (SELECT tblb_ID FROM tblB)

正如评论的那样,您的原始查询应该可以工作。鉴于您更新的信息,这看起来像是正确的查询:

SELECT id
FROM tblA as a
WHERE NOT EXISTS 
(
    SELECT * FROM tblB AS b
    WHERE a.id = b.tblb_ID
)

【讨论】:

  • 已修改以匹配您的列名。
【解决方案2】:

试试这个:

SELECT id FROM tblA WHERE id IN (SELECT id FROM tblB) AND id NOT IN (SELECT id2 FROM tblB)

【讨论】:

    【解决方案3】:

    这样的事情怎么样:

    SELECT a.id
    FROM tblA AS a
    LEFT JOIN tblB as b
    ON a.id = b.id
    WHERE b.id IS NULL
    

    应该为您提供 A 中不存在于 B 中的所有值,仅与 B.id 进行比较

    【讨论】:

      【解决方案4】:

      您的tblB中列的描述与示例数据不一致,显示第一列为tblb_ID。如果那是正确的名称,那么

      SELECT id
      FROM tblA as a
      WHERE NOT EXISTS 
      (
      SELECT * FROM tblB AS b
      WHERE a.id = b.id
      )
      

      无效,应标记为语法错误,因为没有 b.id。如果不是这种情况,您需要报告一个错误。

      也就是说,我会将推荐的修复修改为

      SELECT id
      FROM tblA as a
      WHERE NOT EXISTS 
      (
          SELECT 1 FROM tblB AS b
          WHERE a.id = b.tblb_ID
      )
      

      因为这简化了查询处理器的工作并更好地传达 你的意图。

      SELECTSELECT * 的含义经常被误解。 SELECT是关系代数中PROJECT的SQL实现: 它指定要返回的(不是行)。 SELECT * 返回 所有列;如果 SQL 不是第四代时代的遗物 语言,我们可以省去SELECT *,因为 project all 是 与无投影相同。

      在存在测试中,没有投影,即没有列 选择。所有关键信息都在FROMWHERE 中。一种 row -- 整行 -- 要么满足WHERE 测试,要么不满足。 该行的值不会在任何地方返回。不可用 例如,外部查询。 “选择”毫无意义;它是 只是因为语法需要它。

      通过说SELECT 1,我们强调这是一个布尔测试,并且 没有任何东西被“选择”本身

      【讨论】:

        猜你喜欢
        • 2019-12-12
        • 1970-01-01
        • 2012-02-10
        • 2021-04-22
        • 1970-01-01
        • 2012-08-04
        • 1970-01-01
        • 1970-01-01
        • 2015-06-07
        相关资源
        最近更新 更多