SQL Server の JOIN と CASE ステートメント: よくある落とし穴
SQL Server 2008 R2 (およびそれ以降のバージョン) では、CASE
条件内で直接 JOIN
ステートメントを使用して結合基準を定義しようとすると、構文エラーが発生する可能性があります。 この理由と解決方法を見てみましょう。
sys.partitions
と sys.allocation_units
の関係を考えてみましょう。結合は sys.allocation_units.type
の値に依存します。 素朴なアプローチは次のようになります:
SELECT * FROM sys.indexes i JOIN sys.partitions p ON i.index_id = p.index_id JOIN sys.allocation_units a ON CASE WHEN a.type IN (1, 3) THEN a.container_id = p.hobt_id WHEN a.type IN (2) THEN a.container_id = p.partition_id END
これにより、「'=' 付近の構文が正しくありません」というエラーが発生します。 問題は、CASE
式自体が結合条件に適したブール値 (TRUE/FALSE) の結果を生成しないことです。 代わりに、a.container_id = p.hobt_id
または a.container_id = p.partition_id
のいずれかを返しますが、どちらも単独では有効な結合条件ではありません。
正しいアプローチ: ブール評価
これを修正するには、ブール値を生成する CASE
式が必要です。 これを実現するには、true の場合は 1、false の場合は 0 を返すように CASE
ステートメントを構造化し、その結果を 1:
SELECT * FROM sys.indexes i JOIN sys.partitions p ON i.index_id = p.index_id JOIN sys.allocation_units a ON CASE WHEN a.type IN (1, 3) AND a.container_id = p.hobt_id THEN 1 WHEN a.type IN (2) AND a.container_id = p.partition_id THEN 1 ELSE 0 END = 1
現在、CASE
ステートメントは、適切な条件 (a.type
に基づく) と等価性チェック (a.container_id = p.hobt_id
または a.container_id = p.partition_id
) の両方が true の場合にのみ 1 と評価されます。 = 1
比較により、JOIN
条件に必要なブール値の結果が得られます。 この改訂されたクエリにより、テーブルが正しく結合されます。 このメソッドにより、JOIN
条件が true または false の値に評価されることが保証され、結合が意図したとおりに機能できるようになります。
以上がCASE ステートメントは SQL Server の JOIN 条件で使用できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。