2

単純な結合を考えてみましょう:

Select TableB.* 
From TableA 
Inner Join TableB 
    On TableB.ID = TableA.ID

私がやりたいことは、パラメーターに応じて結合するテーブルを決定することです。次の構文は有効ではありませんが、目的を説明するために書きました。

Select TableD.* 
From TableA 
Inner Join 
    [If @useTableC = 1 Then Join to TableC Else Join to TableB] As TableD

TableB と TableC の両方に同一の列があります。

この種の結合を作成するにはどうすればよいですか。この例は、実際にははるかに大きなクエリのごく一部であるため、If...Else ステートメントだけを使用することはできないことに注意してください。

どうもありがとう!

4

4 に答える 4

6

通常、複数のステートメントで書き直すことを好みますが、本当に必要な場合は次のようにします。

SELECT td.*
FROM TableA ta
JOIN (
    SELECT tc.* FROM TableC Where @useTableC = 1
    UNION ALL
    SELECT tb.* FROM TableB Where @useTableC = 0
) td ON ( /* JOIN CONDITION MISSING */)
于 2012-04-30T15:20:09.680 に答える
1

残念ながら、T-SQL にはこれをサポートする構文がありません。少し前にこれをいじくり回しましたが、(Left Outer joins を使用して) 私を助けてくれたこの記事を見つけるまで、解決策を思いつくことができませんでした。ここにあります

于 2012-04-30T15:22:41.880 に答える
0

いい解決策だ、ジェラルド!ユニオンを使用してもパフォーマンスが低下することはありません。理由はわかりませんが (誰かがここのギャップを埋めることができるかもしれません)、実行計画では、コンスタント スキャンの I/O コストが 0 であることが示されています。

ただし、このアプローチは、TableB と TableC のスキーマが同一であることに依存します。複数のステートメントでこれを行い、TableB と TableC で異なるスキーマをサポートするには、次のアプローチを検討します。

DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT td.* FROM TableA ta INNER JOIN Table' + 
    CASE WHEN @useTableC = 1 THEN 'C' ELSE 'B' END + ' td ON ta.ID = td.ID'
EXEC sp_executesql @sql

対応するスキーマを決定し、それに応じてデータを読み取るのは、アプリケーション コード次第であることに注意してください。

于 2012-04-30T16:23:12.100 に答える
0

@Gerardo Limaの答えは素晴らしいですが、代わりに動的SQLでクエリを構築することもできます。これにより、一連の if ステートメントを使用して、必要な数の if ステートメントを使用して、必要な数の結合を追加したり、追加したりできなくなります。大雑把で大まかな例として:

declare @sql varchar(8000)

set @sql = 'Select TableD.*  From TableA '

if @usertableC = 1 
then select @sql = @sql + ' innner join tableC'

if @usertableC != 1
then select @sql = @sql + ' innner join tableB

exec @sql

「動的 sqlの呪いと祝福」で動的 sql の良い議論があります。

于 2012-04-30T16:05:47.887 に答える