1

次のような 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は使えますか?

このクエリを実行するには、より効率的なソリューションを見つける必要があります。

どうもありがとうございました。

4

4 に答える 4

2

元のクエリと同じ結果を返すには、次のものが必要です。

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

結合の外側でグループ化を行うと、クエリのセマンティクスが変わります。特に、T1 に重複がある場合でも、COD/NAME ごとに 1 行しか返されません。これは望ましいことかもしれません。ただし、元のクエリには重複があります。

また、 TAB1 に NOLOCK があるのに TAB2 にはないのはなぜですか?

于 2012-06-27T16:45:26.150 に答える
0

サブセレクトを使いたくないのはなぜですか?これを外部の applyステートメントに置き換えることができます(私の観点からは、この方が適切に見えます) が、ほとんどの場合、同じ実行計画が得られます。はい、実際にはインデックス (TAB2 テーブルの COD にインデックスがあると仮定します) とデータ (両方のテーブルの行数は多かれ少なかれ大きく、TAB2 の行数は TAB1 の行数よりも確実に大きいと仮定します) に依存します。 )。

COD と NAME でグループ化するソリューションは、最悪のソリューションです。サブクエリを使用したソリューションは、外部適用と同じです。外部適用による解決策は、多かれ少なかれ良い解決策です (クロス適用を使用する方が良いですが、そのような場合、TAB1 に関連する行がない場合、TAB1 に行がないことを確認する必要があります)。

于 2012-06-27T17:04:48.957 に答える
0

はい、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
于 2012-06-27T16:20:53.053 に答える
0
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;
于 2012-06-27T16:21:14.123 に答える