2011-07-18 11 views
0

私は、サブクエリ内のレコードを1つだけ選択する結合にサブクエリを変更しようとしています。実行する分を引き継ぐ、各見つかったレコードのためにサブクエリを実行しているようだ:SQL:サブクエリをジョインに変換する:ネストされたjoin where節の外部テーブルを参照する方法?

select afield1, afield2, (
    select top 1 b.field1 
    from anothertable as b 
    where b.aForeignKey = a.id 
    order by field1 
) as bfield1 
from sometable as a 

私は関連レコードを選択するだけにしようとすると、それは、ネストされた中でa.idをバインドする方法を知りません。選択します。

select afield1, afield2, bfield1 
from sometable a left join (
    select top 1 id, bfield, aForeignKey 
    from anothertable 
    where anothertable.aForeignKey = a.id 
    order by bfield) b on 
     b.aForeignKey = a.id 
-- Results in the multi-part identifier "a.id" could not be bound 

ネストしたwhere句に値をハードコードすると、選択期間は60秒から5秒に短縮されます。誰もが内部テーブルのすべてのレコードを処理していない2つのテーブルを結合する方法に関する提案がありますか?

EDIT:

私は

left outer join (
    select *, row_number() over (partition by/order by) as rank) b on 
    b.aforeignkey = a.id and b.rank = 1 

を追加することになったが22M行に対して〜50秒から8に行ってきました。

答えて

2

はこれを試してみてください:

WITH qry AS 
(
    SELECT afield1, 
      afield2, 
      b.field1 AS bfield1, 
      ROW_NUMBER() OVER(PARTITION BY a.id ORDER BY field1) rn 
     FROM sometable a LEFT JOIN anothertable b 
     ON b.aForeignKey = a.id 
) 
SELECT * 
    FROM qry 
WHERE rn = 1 
+0

を試してみてください?私はこれが 'a.id = b.aForeignKey'のb(select * from anothertable b)bと同じであると思うでしょう。これらが同じ場合、クエリは5秒からほぼ1分になりますが、より高速です見つかったレコードごとに実行されるサブクエリよりも優先されます。 +1は動作中のソリューションです。たぶん、テーブル値関数を作成しますか? –

+0

あなたは間違いなく正しい道を歩んでいます。上記のようなランク(row_number)を含め、すべてを選択する場合は、プライマリキーのパラメータまたはnull値を受け入れるインラインテーブル値関数にCTEを変換しました。今度は、dbo.sometablef(/ * aForeignKey */1)をrank = 1'から選択することができます。ありがとう! –

+0

問題はTVFのパラメータをハードコード化しなければならなかったので、私は上記のランクでTVFを作ってからランク= 1の場所に参加しました。 –

0

は初めてと思われる行を選択し、これはすべての行を選択しないだろう、この

select afield1, 
afield2, 
bfield1 
from sometable a 
left join 
(select top 1 id, bfield, aForeignKey from anothertable where aForeignKey in(a.id) order by bfield) b on b.aForeignKey = a.id 
+0

私が見つけたものから、in(a.id)はバインドできないという同じエラーを返します。 –

関連する問題