web-dev-qa-db-fra.com

Déclaration conditionnelle de JOIN SQL Server

Est-il possible de faire ce qui suit:

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

Si oui, quelle est la syntaxe correcte?

48
Squ1rr3lz

Je pense que ce que vous demandez fonctionnera en joignant la table Initial à la fois Option_A et Option_B en utilisant LEFT JOIN, qui produira quelque chose comme ceci:

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

Exemple de code:

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

Une fois que vous avez fait cela, vous "ignorez" l'ensemble de NULLS. L'astuce supplémentaire est ici dans la ligne SELECT, où vous devez décider quoi faire avec les champs NULL. Si les tables Option_A et Option_B sont similaires, vous pouvez utiliser la fonction COALESCE pour renvoyer la première valeur NON NULL (comme dans l'exemple).

L'autre option est que vous devrez simplement lister les champs Option_A et Option_B, et laisser ce qui utilise le ResultSet pour gérer la détermination des champs à utiliser.

58
simo.37920

Ceci est juste pour ajouter le point que la requête peut être construite dynamiquement en fonction de conditions. Un exemple est donné ci-dessous.

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

Je ne suis pas d'accord avec la solution suggérant 2 jointures restantes. Je pense qu'une fonction table-value est plus appropriée afin que vous n'ayez pas toutes les jointures coalescentes et supplémentaires pour chaque condition que vous auriez.

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