si autre chose au sein de CTE?

Je veux exécuter une instruction select au sein de CTE basée sur une codition. quelque chose comme ci-dessous

;with CTE_AorB ( if(condition) select * from table_A else select * from table_B ), CTE_C as ( select * from CTE_AorB // processing is removed ) 

Mais j'ai une erreur à ce sujet. Est-il possible d'avoir autre chose au sein des CTE? Si ce n'est pas le cas, ou une meilleure approche.

Merci.

essayer:

 ;with CTE_AorB ( select * from table_A WHERE (condition true) union all select * from table_B WHERE NOT (condition true) ), CTE_C as ( select * from CTE_AorB // processing is removed ) 

la key avec une condition de search dynamic est de s'assurer qu'un index est utilisé, Voici un article très complet sur la façon de gérer ce sujet:

Conditions de search dynamic dans T-SQL par Erland Sommarskog

il couvre tous les problèmes et methods d'essayer d'écrire des requêtes avec plusieurs conditions de search facultatives. Ce n'est pas la duplication de code, mais l'utilisation d'un index. Si votre requête ne parvient pas à utiliser un index, il se produira mal. Il existe plusieurs techniques qui peuvent ou non permettre l'utilisation d'un index.

voici la table des matières:

   introduction
       L'étude de cas: la search d'ordres
       La database Northgale
    SQL dynamic
       introduction
       Utilisation de sp_executesql
       Utilisation du CLR
       Utilisation d'EXEC ()
       Lorsque la caching n'est pas vraiment ce que vous voulez
    SQL statique
       introduction
       x = @x OR @x EST NUL
       Utilisation des instructions IF
       Le sac d'astuces d'Umachandar
       Utilisation de tables temporaires
       x = @x ET @x N'EST PAS NUL
       Gestion des conditions complexes
    Solutions hybrides - Utilisation de SQL statique et dynamic
       Utiliser des vues
       Utilisation des fonctions de table en ligne
    Conclusion
    Commentaires et remerciements
    Historique des révisions 

Si vous utilisez la bonne version de SQL Server 2008, vous pouvez utiliser une technique supplémentaire, voir: Conditions de search dynamics dans la version T-SQL pour SQL 2008 (SP1 CU5 et versions ultérieures)

Si vous êtes sur cette version correcte de SQL Server 2008, vous pouvez simplement append OPTION (RECOMPILE) à la requête et la valeur de la variable locale lors de l'exécution est utilisée pour les optimizations.

Considérez ceci, OPTION (RECOMPILE) prendra ce code (où aucun index ne peut être utilisé avec ce désordre de OR ):

 WHERE (@search1 IS NULL or Column1=@Search1) AND (@search2 IS NULL or Column2=@Search2) AND (@search3 IS NULL or Column3=@Search3) 

et l'optimiser au moment de l'exécution (à condition que seulement @ Search2 ait été passé avec une valeur):

 WHERE Column2=@Search2 

et un index peut être utilisé (si vous en avez défini un sur Column2)

N'essayez jamais de mettre des conditions comme IF dans une seule requête. Même si vous parvenez à le retirer, c'est le seul moyen sûr de tuer la performance. Rappelez-vous, une seule déclaration signifie un plan unique, et le plan devra être généré de manière à satisfaire les deux cas, lorsque la condition est vraie et lorsque la condition est fausse, à la fois . Cela entraîne généralement le pire plan possible, car la «condition» crée généralement un path d'access mutuellement exclusif pour le plan et l'union des deux résultats dans un balayage de table toujours de bout en bout.

Votre meilleure approche, pour ceci et beaucoup d'autres raisons, est de tirer le FI en dehors de la déclaration:

 if(condition true) select * from table_A else select * from table_B 

Je pense que les choses IF ELSE pourraient avoir une caching médiocre si votre condition de twig se returnne. Peut-être que quelqu'un de mieux informé peut commenter.

Une autre façon serait d'UNION ALL avec les clauses WHERE comme suggéré par d'autres. L'UNION ALL replaceait le IF ELSE

Si vous utilisez un paramètre, vous n'avez besoin que d'une seule instruction.

 @ID (Some parameter) ;with CTE ( select * from table_A WHERE id = @ID union all select * from table_B WHERE (id = @ID and condition) )