web-dev-qa-db-ja.com

条件付きJOINステートメントSQL Server

以下を行うことは可能ですか?

IF [a] = 1234 THEN JOIN ON TableA 
ELSE JOIN ON TableB

もしそうなら、正しい構文は何ですか?

48
Squ1rr3lz

Initialテーブルを両方のOption_AおよびOption_BLEFT JOINを使用すると、次のようなものが生成されます。

Initial LEFT JOIN Option_A LEFT JOIN NULL
OR
Initial LEFT JOIN NULL LEFT JOIN Option_B

サンプルコード:

SELECT i.*, COALESCE(a.id, b.id) as Option_Id, COALESCE(a.name, b.name) as Option_Name
FROM Initial_Table i
LEFT JOIN Option_A_Table a ON a.initial_id = i.id AND i.special_value = 1234
LEFT JOIN Option_B_Table b ON b.initial_id = i.id AND i.special_value <> 1234

これを行うと、NULLのセットを「無視」します。ここでの追加のトリックは、NULL行をどうするかを決める必要があるSELECT行にあります。 Option_AテーブルとOption_Bテーブルが類似している場合、COALESCE関数を使用して、最初のNON NULL値を返すことができます(例のとおり)。

もう1つのオプションは、Option_AフィールドとOption_Bフィールドをリストするだけで、ResultSetを使用しているものに、使用するフィールドの決定を処理させるだけです。

58
simo.37920

これは、条件に基づいてクエリを動的に構築できるという点を追加するだけです。以下に例を示します。

DECLARE @a INT = 1235
DECLARE @sql VARCHAR(MAX) = 'SELECT * FROM [sourceTable] S JOIN ' + IIF(@a = 1234,'[TableA] A ON A.col = S.col','[TableB] B ON B.col = S.col') 

EXEC(@sql)
--Query will be
/*
SELECT * FROM [sourceTable] S JOIN [TableB] B ON B.col = S.col
*/
5
Jithin Shaji

2つの左結合を提案するソリューションに同意しません。テーブル値関数の方が適切だと思うので、条件ごとにすべての合体および追加の結合を行う必要はありません。

CREATE FUNCTION f_GetData (
    @Logic VARCHAR(50)
) RETURNS @Results TABLE (
    Content VARCHAR(100)
) AS
BEGIN
    IF @Logic = '1234'
        INSERT @Results
            SELECT Content
            FROM Table_1
    ELSE
        INSERT @Results
            SELECT Content
            FROM Table_2
    RETURN
END
GO

SELECT *
FROM InputTable
    CROSS APPLY f_GetData(InputTable.Logic) T
1
Jason W