【问题标题】:What happens if the sub-query on an IN operator fails?如果 IN 运算符的子查询失败会怎样?
【发布时间】:2020-01-07 16:17:49
【问题描述】:

我有一个 T-SQL 查询,我在其中使用 IN 运算符查找 GUID 在子查询结果中的所有记录。但是,我最近对架构进行了更改,因此 Table6 没有 GUID 字段,现在有一个 AlternateID 字段。因此,如果您运行 IN 运算符的子查询,它就会失败。但是,如果我作为一个整体执行查询,它总是返回 TableGUIDResolving 表中的所有记录。几乎就好像 IN 运算符对所有记录都返回 TRUE,因为子查询失败。

我已尝试修复子查询,当我这样做时它按预期执行。

有人可以帮我解释一下吗?这种行为是故意的吗?

SELECT ID 
FROM TableGUIDResolving 
WHERE GUID IN (SELECT AlternateID AS GUID FROM Table1
               UNION
               SELECT GUID FROM Table2
               UNION
               SELECT GUID FROM Table3
               UNION
               SELECT GUID FROM Table4
               UNION
               SELECT GUID FROM Table5
               UNION
               SELECT GUID FROM Table6)

【问题讨论】:

    标签: sql-server subquery in-operator


    【解决方案1】:

    是的。当您使用没有限定列名的子查询时会发生这种情况。你以为你在说:

    select table6.GUID from table6
    

    但这并不存在,所以 SQL 中的作用域规则将其更改为:

    select TableGUIDResolving.GUID from table6
    

    我建议您将逻辑更改为一系列NOT EXISTS

    SELECT ID
    FROM TableGUIDResolving tgr WHERE GUID IN (
    WHERE EXISTS (SELECT 1 FROM Table1 t1 WHERE t1.AlternateID = tgr.GUID) OR
          EXISTS (SELECT 1 FROM Table2 t2 WHERE t2.GUID = tgr.GUID) OR
          EXISTS (SELECT 1 FROM Table3 t3 WHERE t3.GUID = tgr.GUID) OR
          EXISTS (SELECT 1 FROM Table4 t4 WHERE t4.GUID = tgr.GUID) OR
          EXISTS (SELECT 1 FROM Table4 t5 WHERE t5.GUID = tgr.GUID) OR
          EXISTS (SELECT 1 FROM Table4 t6 WHERE t6.GUID = tgr.GUID) 
    

    如果您在每个表中的GUID/AlternateID 上都有索引,那么这应该会有更好的性能。

    【讨论】:

    • 如果是这种情况,为什么它不抱怨,例如,table2 有一个 guid 列?
    • @Andrew 。 . .如果它在子查询中引用的表中找到列,则它使用那里的列。如果没有,它会在外部范围内查找。
    • 感谢您的回复。在互联网上很难找到答案,因为“IN”这个词搜索不好。
    猜你喜欢
    • 2015-01-30
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 2021-06-21
    • 1970-01-01
    相关资源
    最近更新 更多