2010-06-10 9 views
1

Puis-je refactoriser les instructions SQL CASE ci-dessous en single pour chaque cas?SELECT..CASE - Refactor T-SQL

SELECT 
    CASE RDV.DOMAIN_CODE WHEN 'L' THEN CN.FAMILY_NAME ELSE NULL END AS [LEGAL_FAMILY_NAME], 
    CASE RDV.DOMAIN_CODE WHEN 'L' THEN CN.GIVEN_NAME ELSE NULL END AS [LEGAL_GIVEN_NAME], 
    CASE RDV.DOMAIN_CODE WHEN 'L' THEN CN.MIDDLE_NAMES ELSE NULL END AS [LEGAL_MIDDLE_NAMES], 
    CASE RDV.DOMAIN_CODE WHEN 'L' THEN CN.NAME_TITLE ELSE NULL END AS [LEGAL_NAME_TITLE], 

    CASE RDV.DOMAIN_CODE WHEN 'P' THEN CN.FAMILY_NAME ELSE NULL END AS [PREFERRED_FAMILY_NAME], 
    CASE RDV.DOMAIN_CODE WHEN 'P' THEN CN.GIVEN_NAME ELSE NULL END AS [PREFERRED_GIVEN_NAME], 
    CASE RDV.DOMAIN_CODE WHEN 'P' THEN CN.MIDDLE_NAMES ELSE NULL END AS [PREFERRED_MIDDLE_NAMES], 
    CASE RDV.DOMAIN_CODE WHEN 'P' THEN CN.NAME_TITLE ELSE NULL END AS [PREFERRED_NAME_TITLE] 

FROM dbo.CLIENT_NAME CN 
JOIN dbo.REFERENCE_DOMAIN_VALUE RDV 
ON CN.NAME_TYPE_CODE = RDV.DOMAIN_CODE AND RDV.REFERENCE_DOMAIN_ID = '7966' 

Répondre

1

Non, vous aurez besoin de 8 déclarations séparées comme case et d'autres variantes ne peuvent être utilisés dans un select pour modifier les résultats d'une seule colonne, et non une série de colonnes.

1

Si RDV.DOMAIN_COD ne peut utiliser que 'P' ou 'L', utiliser NULLIf. C'est plus propre.

NULLIF (expression , expression) 

NULLIF équivaut à une expression CASE recherchée dans laquelle les deux expressions sont égales et l'expression résultante est NULL.

SELECT 
NullIf('P', RDV.DOMAIN_CODE) AS [LEGAL_FAMILY_NAME], 
... 
NullIf('L', RDV.DOMAIN_CODE) AS [PREFERRED_FAMILY_NAME], 
... 
+0

Désolé je ne comprends pas-comment le faites-vous vraiment avec nullif. – josephj1989

+0

Oui John, pouvez-vous s'il vous plaît donner un exemple. Merci – Sreedhar

+0

Ceci est faux, il retournera NULL pour Legal_Family_Name s'il s'agit du nom préféré et NULL pour le nom de famille préféré s'il s'agit du nom légal. Mais il ne renverra pas le nom de famille légal réel ou le nom préféré ... – Cervo

1

Étant donné qu'une expression CASE renvoie une valeur unique, vous ne pouvez pas prendre huit expressions CASE retournant 8 valeurs et créer une seule expression CASE qui renvoie tous les huit.

0

Une alternative moins efficace sans cas:

SELECT LEGAL_FAMILY_NAME, LEGAL_GIVEN_NAME, LEGAL_MIDDLE_NAMES, LEGAL_NAME_TITLE, 
     PREFERRED_FAMILY_NAME, PREFERRED_GIVEN_NAME, PREFERRED_MIDDLE_NAMES, PREFERRED_NAME_TITLE 
FROM dbo.REFERENCE_DOMAIN_VALUE RDV 
LEFT OUTER JOIN 
    (SELECT 
     NAME_TYPE_CODE, 
     FAMILY_NAME AS [LEGAL_FAMILY_NAME], 
     GIVEN_NAME AS [LEGAL_GIVEN_NAME], 
     MIDDLE_NAMES AS [LEGAL_MIDDLE_NAMES], 
     NAME_TITLE AS [LEGAL_NAME_TITLE] 
    FROM dbo.CLIENT_NAME 
    WHERE NAME_TYPE_CODE = 'L') LN ON RDV.DOMAIN_CODE = LN.NAME_TYPE_CODE 
LEFT OUTER JOIN 
    (SELECT 
     NAME_TYPE_CODE, 
     FAMILY_NAME AS [PREFERRED_FAMILY_NAME], 
     GIVEN_NAME AS [PREFERRED_GIVEN_NAME], 
     MIDDLE_NAMES AS [PREFERRED_MIDDLE_NAMES], 
     NAME_TITLE AS [PREFERRED_NAME_TITLE] 
    FROM dbo.CLIENT_NAME 
    WHERE NAME_TYPE_CODE = 'P') PN ON RDV.DOMAIN_CODE = PN.NAME_TYPE_CODE 
    WHERE RDV.REFERENCE_DOMAIN_ID = '7966' 

Vous pouvez également utiliser une table temporaire ou variable de table avec toutes les 8 colonnes, puis faire deux inserts. Vous pouvez également utiliser UNION ALL. Je suppose que les 8 déclarations de cas sont les plus efficaces. Cela est particulièrement vrai si vous avez une clé où vous voulez un certain type de ClientID, noms juridiques, noms préférés afin que vous enveloppez un MAX autour des cas ou quelque chose et grouper par un ClientID ......

Vous pourrait générer le script SQL en utilisant syscols/INFORMATION_SCHEMA.columns avec deux when case pour chaque colonne 'CASE WHAIN DOMAIN_CODE =' P '' THEN '+ COLUMN_NAME +' ELSE NULL END COMME PREFERRED_ '+ COLUMN_NAME puis un autre pour L. Vous pourriez faire une BOUCLE pour que le même code s'exécute une fois pour P et une fois pour L et l'amène à une boucle. Ensuite, vous pouvez EXEC la chaîne directement, ou l'IMPRIMER et le mettre dans votre script SQL. En tout cas pour seulement 8 colonnes je couperais/collerais les instructions de cas ...

Mais de toute façon en général T-SQL est limité à pouvoir faire pour eaches sur des colonnes. Soit vous générez le script en utilisant un générateur de code (fait dans t-sql ou un autre langage de programmation), soit vous repensez votre problème d'une autre manière. Mais plusieurs fois vous obtenez de meilleures performances à partir du code copier/coller en double. Et plusieurs fois cela ne vaut pas la peine d'écrire un générateur de code externe (c'est-à-dire juste pour 8 instructions de cas).