【问题标题】:Oracle SQL: Check if entry exists and return if it DOESN'TOracle SQL:检查条目是否存在,如果不存在则返回
【发布时间】:2020-02-20 03:23:29
【问题描述】:

我想根据第二个表中的值检查一个表中是否存在条目,但如果不存在则从第二个表中选择值。

为了解释,我有一个名为devices 的表和一个名为tests 的表。 devices 中的每个设备都有一个唯一的标识符(一个整数)。 tests 中的每个测试都引用了运行测试的设备的唯一标识符。因此,每个test 都与一个device 相关联。然而,并不是每个device 都经过测试。此外,可以在单个设备上运行多个测试。

所以我想要SELECTdevices 中的所有条目,这些条目未被tests 中的至少一个条目引用。

【问题讨论】:

    标签: sql oracle join subquery left-join


    【解决方案1】:

    谢谢,成功了。我承认,我更改了上面表格的名称,以便更容易提出问题,但这是我得出的结论并且它工作正常:

    SELECT DEVICE.ID
    FROM DEVICE
    WHERE DEVICE.ID NOT IN (
    SELECT TEST.DEVICEID FROM TEST WHERE TEST.DEVICEID=DEVICE.ID)
    ORDER BY DEVICE.ID
    

    到底简单。不能说我是 SQL 的初学者,可以吗? :)

    【讨论】:

    • 我反对使用NOT IN,因为在处理NULLs 时会导致意外行为。
    【解决方案2】:

    所以我要选择的是设备中的所有条目,这些条目未被测试中的至少一个条目引用。

    假设以下数据结构:

    devices(id)
    tests(id, device_id)
    

    你可以使用not exists:

    select d.*
    from devices
    where not exists (
        select 1
        from tests t
        where t.device_id = d.id
    )
    

    或左连接反模式:

    select d.*
    from devices d
    left join tests t on t.device_id = d.id
    where t.id is null
    

    【讨论】:

      【解决方案3】:

      您可以使用简单的NOT IN 来实现您想要的结果(假设id 作为devices 中的唯一标识符,device_id 作为testsdevices.id 的外键,以及tests.device_id有一个NOT NULL 属性:

      SELECT *
      FROM devices
      WHERE id NOT IN (
          SELECT DISTINCT device_id
          FROM tests
      );
      

      这应该适用于大多数主要的 RDBMS;由于您尚未指定您使用的是哪一个,因此您的里程可能会有所不同。

      【讨论】:

      • IN/NOT IN/EXISTS 子查询已经隐式不同(至少在 Oracle 中)。
      • @WilliamRobertson 谢谢。这个答案是在添加 Oracle 标题/标签之前做出的。我将暂时保持原样,
      猜你喜欢
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      • 2011-12-26
      • 2011-05-12
      • 1970-01-01
      • 2017-11-17
      相关资源
      最近更新 更多