【问题标题】:SELECT in SQL Server - alternative to SUBQUERYSQL Server 中的 SELECT - SUBQUERY 的替代方案
【发布时间】:2012-06-29 03:40:28
【问题描述】:

我有一个这样的 SELECT 语句:

SELECT 
T1.COD,
T1.NAME, 
(SELECT MAX(T2.DATA)
  FROM dbo.TAB2 T2
  WHERE T2.COD = T1.COD) AS ENDDATA
FROM dbo.TAB1 AS T1 WITH (NOLOCK) 

有没有使用 SUBQUERY 的替代方法?可以使用JOIN吗?

我必须找到一个更有效的解决方案来运行这个查询。

非常感谢。

【问题讨论】:

  • 子查询很好,因为你必须left (select max(data), code from dbo.tab2 group by code) t2 on t1.code = t2.code

标签: sql sql-server select subquery


【解决方案1】:

是的,您可以使用 JOIN:

SELECT 
   T1.COD,
   T1.NAME, 
   MAX(T2.DATA) AS ENDDATA
FROM dbo.TAB1 AS T1 WITH (NOLOCK) 
JOIN dbo.TAB2 T2 WITH (NOLOCK) -- Assumed
  ON T2.COD = T1.COD
GROUP BY
   T1.COD,
   T1.NAME

【讨论】:

    【解决方案2】:
    SELECT   T1.COD,
             T1.NAME, 
             MAX(T2.DATA)
    FROM     TAB1 AS T1
    JOIN     TAB2 AS T2
    ON       T2.COD = T1.COD
    GROUP BY T1.COD,
             T1.NAME;
    

    【讨论】:

      【解决方案3】:

      要返回与原始查询相同的结果,您需要以下内容:

      SELECT T1.COD, T1.NAME, s.ENDDATA
      FROM dbo.TAB1 T1 WITH (NOLOCK)  left outer join
           (SELECT t2.cod, MAX(T2.DATA) as EndData
            FROM dbo.TAB2 T2
            group by T2.COD
           ) s
           on t1.cod = s.cod
      

      在连接之外进行分组会改变查询的语义。特别是,您将只返回每个 COD/NAME 的一行,即使 T1 中可能存在重复。这可能是可取的。但是,您的原始查询会有重复项。

      另外,为什么你在 TAB1 上有 NOLOCK 而在 TAB2 上没有?

      【讨论】:

        【解决方案4】:

        为什么不想使用子选择?您可以将其替换为 outer apply 语句(从我的角度来看,这看起来更好),但在大多数情况下,您将获得相同的执行计划。是的,实际上它取决于您的索引(我假设您在 TAB2 表中的 COD 上有索引)和数据(我假设两个表中的行数或多或少都很大,并且 TAB2 中的行数肯定大于 TAB1 中的行数)。

        按 COD 和 NAME 分组的解决方案是最差的解决方案。子查询的解决方案与外部应用相同。带有外部应用的解决方案或多或少是好的解决方案(使用交叉应用更好,但在这种情况下,您应该确保 TAB1 中没有行而 TAB1 中没有相关行)。

        【讨论】:

          猜你喜欢
          • 2022-01-07
          • 2011-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多