【问题标题】:Issue with Subquery in Where ClauseWhere 子句中的子查询问题
【发布时间】:2015-10-13 20:23:05
【问题描述】:

我有一个选择查询:

Select  left([Foundation_Account_Name],4)
     From [dbo].[tbl_Foundation_Account]    
        Where [Foundation_Account_Name] 

返回

MAZA
SUMI
APLH

我有第二个 Select 查询从临时表中选择相同的字段

Select left([Foundation Account Name],4) 
            From [dbo].[Import_tbl_RDO]
                 Where [Foundation Account Name] IS NOT NULL))

返回

SUMI

我想在 where 子句中使用这些选择查询,当我在 tbl_Foundation_Account 上运行选择时,它将只返回 SUMI。我的想法是这样的,

Select  left([Foundation_Account_Name],4)
     From [dbo].[tbl_Foundation_Account]    
        Where [Foundation_Account_Name] = (Select  left([Foundation_Account_Name],4)
     From [dbo].[tbl_Foundation_Account]    
        Where [Foundation_Account_Name] = (Select left([Foundation Account Name],4) 
            From [dbo].[Import_tbl_RDO]
                 Where [Foundation Account Name] IS NOT NULL))

理论上(至少在我的脑海中)主选择查询只会从tbl_Foundation_Account 中选择记录,其中第二个和第三个选择查询彼此相等,应该是SUMI。现在这只是没有回报,而且我越深入兔子洞,我就越困惑。这个查询是不是搞砸了,还是我接近达到我想要的结果

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您可以使用intersect 从两个查询中获取共同的结果。

    Select left([Foundation_Account_Name],4)
    From [dbo].[tbl_Foundation_Account]    
    INTERSECT 
    Select left([Foundation Account Name],4) 
    From [dbo].[Import_tbl_RDO]
    Where [Foundation Account Name] IS NOT NULL
    

    【讨论】:

      【解决方案2】:

      只是建立在您已经拥有的基础上...并将表格连接在一起... 虽然 intersect 看起来更干净......

      with A as (SELECT left([Foundation_Account_Name],4) ID
                 FROM [dbo].[tbl_Foundation_Account]), 
           b as (SELECT left([Foundation Account Name],4) ID
                 FROM [dbo].[Import_tbl_RDO])
      
      SELECT C.left([Foundation_Account_Name],4) 
      FROM [dbo].[tbl_Foundation_Account]  C
      INNER JOIN A on A.ID = C.left([Foundation_Account_Name],4)
      INNER JOIN B on A.ID = B.ID
      

      【讨论】:

      • 为什么需要表b?通过删除与之相关的所有内容,您的查询不会完美运行吗?
      • 我认为你的意思是我为什么需要 A。A 与 c 相同。你说得对,我真的不需要 A 也不需要 A intersect B join。我没有查看我认为所有 3 个不同的表名。
      • 我完全是说 b,因为你需要保留 INNER JOIN A on A.ID = C.left([Foundation_Account_Name],4) 行,除了 A 和 b 是一样的。
      【解决方案3】:

      你真正想做的事情是这样的:

      SELECT {{FIELDS TO QUERY}}
      FROM [dbo].[tbl_Foundation_Account] fa    
      WHERE EXISTS (
          SELECT *
          FROM [dbo].[Import_tbl_RDO] rdo
          WHERE left(rbo.[Foundation Account Name],4) = left(fa.[Foundation Account Name],4)
      )
      

      或者,如果您需要访问来自Import_tbl_RDO 的任何数据,您也可以简单地加入您的表:

      SELECT {{FIELDS TO QUERY}}
      FROM [dbo].[tbl_Foundation_Account] fa    
      INNER JOIN [dbo].[Import_tbl_RDO] rdo
          ON left(rbo.[Foundation Account Name],4) = left(fa.[Foundation Account Name],4)
      

      第二种方法的“缺点”是,如果您有多个符合条件的 Import_tbl_RDO 行,您最终会得到重复的行(可能需要也可能不需要)。

      【讨论】:

        【解决方案4】:

        您的问题与所提出的完全不一样,因为如果您真正想要的结果是临时表上的查询返回的任何结果,那么您为什么不直接使用它呢?

        我想您真正想要的是根据您对临时表的查询结果过滤返回更多列的查询结果。如果临时表查询保证每次只返回一行,那么你可以这样写:

        Select 
          -- column1, column2, ...
        From [dbo].[tbl_Foundation_Account]    
        Where left([Foundation Account Name],4) = (
            Select left([Foundation Account Name],4) 
            From [dbo].[Import_tbl_RDO]
            Where [Foundation Account Name] IS NOT NULL
          )
        

        不过,在某些情况下,临时表查询更有可能返回多行,或者可能不返回。在这种情况下,您可能需要IN 条件:

        Select 
          -- column1, column2, ...
        From [dbo].[tbl_Foundation_Account]    
        Where left([Foundation Account Name],4) IN (
            Select left([Foundation Account Name],4) 
            From [dbo].[Import_tbl_RDO]
            Where [Foundation Account Name] IS NOT NULL
          )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-03
          • 1970-01-01
          • 2012-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多