2013-02-05 3 views
3

J'essaie d'utiliser une valeur de champ calculée dans une clause WHERE dans ma requête, et après quelques recherches, je sais que je dois créer une table dérivée. Je ne suis pas sûr que la syntaxe cependant, puisque mon champ calculé utilise une instruction CASE comme:SQL Server - comment utiliser la table dérivée pour champ calculé?

 CASE T.IsReassigned 
     WHEN 1 THEN DATEDIFF(MINUTE, 
        (SELECT top 1 SXAVWFTaskHistory.CreatedWhenUTC from SXAVWFTaskHistory where TaskID = T.TaskID and StatusID = 7 order by TaskHistoryID desc), 
        SYSDATETIMEOFFSET())       
     ELSE 
     CASE Stat.StatusID  
      WHEN 1 THEN DATEDIFF(MINUTE,TSK.CreatedWhenUTC, SYSDATETIMEOFFSET()) -- time duration between when task is created(use SXAVWFTask.CreatedWhenUTC) and now 
      WHEN 2 THEN DATEDIFF(MINUTE,TSK.CreatedWhenUTC, SYSDATETIMEOFFSET()) -- time duration between when task is created(use SXAVWFTask.CreatedWhenUTC) and now 
      ELSE DATEDIFF(MINUTE,TSK.CreatedWhenUTC, TH.CreatedWhenUTC) 
     END 
    END as TaskItemAge, 

Je veux ensuite utiliser la valeur TaskItemAge dans le où quelque chose comme clause:

WHERE TaskItemAge > @TaskAgeStart AND TaskItemAge < @TaskAgeEnd 

Comment faire J'ai mis cette déclaration CAS dans un sous-select?

** * ** * ** * ** * ** EDIT ** * ** * ** * * * * Désolé, je suis encore un peu confus quant à la façon dont cela fonctionnerait. Voici un grand bout de ma requête:

SELECT TSK.TaskID, --0 
    TH.IsLatest, 
    TH.CreatedWhenUTC as TaskHistoryCreationDate, --10 
    TS.Name AS STATE, 
    CASE T.IsReassigned 
     WHEN 1 THEN DATEDIFF(MINUTE, 
        (SELECT top 1 SXAVWFTaskHistory.CreatedWhenUTC from SXAVWFTaskHistory where TaskID = T.TaskID and StatusID = 7 order by TaskHistoryID desc), 
        SYSDATETIMEOFFSET())       
     ELSE 
     CASE Stat.StatusID  
      WHEN 1 THEN DATEDIFF(MINUTE,TSK.CreatedWhenUTC, SYSDATETIMEOFFSET()) -- time duration between when task is created(use SXAVWFTask.CreatedWhenUTC) and now 
      WHEN 2 THEN DATEDIFF(MINUTE,TSK.CreatedWhenUTC, SYSDATETIMEOFFSET()) -- time duration between when task is created(use SXAVWFTask.CreatedWhenUTC) and now 
      ELSE DATEDIFF(MINUTE,TSK.CreatedWhenUTC, TH.CreatedWhenUTC) 
     END 
    END as TaskItemAge, 
    ctx.ContextTypeName, 
    ctx.ContextDescription, --15 
    TH.TouchedWhenUTC as TaskHistoryModifiedDate 
INTO #ii   
FROM SXAVWFTask TSK 
INNER JOIN SXAVWFTaskHistory TH ON TSK.TaskID = TH.TaskID 
INNER JOIN @PagedTemp T on TH.TaskHistoryID = T.TaskHistoryID 

Where TaskItemAge > @TaskAgeStart AND TaskItemAge < @TaskAgeEnd 
+0

Une table dérivée * est juste n'importe quel ensemble de lignes générées par (c'est-à-dire, dérivées d'une) instruction SELECT. Dans les tables dérivées de SQL Server qui peuvent également être utilisées dans les requêtes, il y a 1) les sous-requêtes, 2) les CTE et 3) les vues. – RBarryYoung

Répondre

2
select * 
from (
     select case ... end as CaseColumn 
     ,  * 
     from YourTable 
     ) as SubQueryAlias 
where CaseColumn between 1 and 2 
1

Andomar c'est la forme correcte (+1), voici votre syntaxe spécifique:

SELECT * 
FROM (
    SELECT *, 
     CASE T.IsReassigned 
      WHEN 1 THEN DATEDIFF(MINUTE, 
         (SELECT top 1 SXAVWFTaskHistory.CreatedWhenUTC from SXAVWFTaskHistory where TaskID = T.TaskID and StatusID = 7 order by TaskHistoryID desc), 
         SYSDATETIMEOFFSET())       
      ELSE 
      CASE Stat.StatusID  
       WHEN 1 THEN DATEDIFF(MINUTE,TSK.CreatedWhenUTC, SYSDATETIMEOFFSET()) -- time duration between when task is created(use SXAVWFTask.CreatedWhenUTC) and now 
       WHEN 2 THEN DATEDIFF(MINUTE,TSK.CreatedWhenUTC, SYSDATETIMEOFFSET()) -- time duration between when task is created(use SXAVWFTask.CreatedWhenUTC) and now 
       ELSE DATEDIFF(MINUTE,TSK.CreatedWhenUTC, TH.CreatedWhenUTC) 
      END 
     END as TaskItemAge 
    FROM BaseTable 
) as DerivedTable 
WHERE TaskItemAge > @TaskAgeStart AND TaskItemAge < @TaskAgeEnd 
1

vous pouvez également utiliser CTE

;WITH cte AS 
    (
    SELECT CASE WHEN ... THEN ... END AS TaskItemAge 
    FROM your_table 
    ) 
    SELECT * 
    FROM cte 
    WHERE TaskItemAge > @TaskAgeStart AND TaskItemAge < @TaskAgeEnd 
+1

J'ai upvoted, mais ma propre opinion est que si vous allez seulement utiliser la sous-requête une fois, l'utilisation de cte est overengineering. –

Questions connexes