Puis-je utiliser l'instruction CASE dans une condition JOIN ?

L'image suivante est une partie de Microsoft SQL Server 2008 R2 System Views. Dans l'image, nous pouvons voir que la relation entre sys.partitions et sys.allocation_units dépend de la valeur de sys.allocation_units.type. Donc, pour les joindre, j'écrirais quelque chose de similaire à ceci :

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 

Mais le code supérieur donne une erreur de syntaxe. Je suppose que c'est à cause de l'instruction CASE. Quelqu'un peut-il m'expliquer un peu ?


Ajouter un message d'erreur :

Msg 102, Level 15, State 1, Line 6 Syntaxe incorrecte près de '=&#39 ;.

! [ceci est l'image] [1]

[1] : http://i.stack.imgur.com/HYmiS.jpg

Solution

Une expression CASE renvoie une valeur de la partie THEN de la clause. Vous pourriez l'utiliser de la manière suivante :

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

Notez que vous devez faire quelque chose avec la valeur retournée, par exemple la comparer à 1. Votre déclaration tente de retourner la valeur d'une affectation ou de tester l'égalité, ce qui n'a aucun sens dans le contexte d'une clause CASE/THEN. (Si BOOLEAN était un type de données, le test d'égalité aurait un sens).

Commentaires (6)

Au lieu de cela, il suffit de joindre les deux tables, et dans votre clause SELECT,

renvoyer les données de celle qui correspond :

Je vous suggère de consulter ce lien [Joints conditionnels dans SQL Server][1] et https://stackoverflow.com/questions/8361183/t-sql-case-statement-in-a-join-on-clause.

Par exemple

    SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id 
        JOIN sys.allocation_units a
            ON a.container_id =
            CASE
               WHEN a.type IN (1, 3)
                   THEN  p.hobt_id 
               WHEN a.type IN (2)
                   THEN p.partition_id
               END 

Edit : Selon les commentaires.

Vous ne pouvez pas spécifier la condition de jointure comme vous le faites... Vérifiez la requête ci-dessus qui n'a pas d'erreur. J'ai enlevé la colonne commune en haut et la valeur de la colonne de droite sera évaluée sur la condition.

[1] : http://weblogs.sqlteam.com/jeffs/archive/2007/04/03/Conditional-Joins.aspx

Commentaires (9)

Essayez ça :

...JOIN sys.allocation_units a ON 
  (a.type=2 AND a.container_id = p.partition_id)
  OR (a.type IN (1, 3) AND a.container_id = p.hobt_id)
Commentaires (1)