2011-03-04 4 views
1

J'ai 2 fonctions de table qui sont très similaires, la seule différence est que j'ai besoin d'un Max() appel supplémentaire sur le second. Je veux les consolider en un, mais je n'arrive pas à comprendre comment le faire.Si déclaration dans la table Valeur fonction

Première fonction

ALTER FUNCTION [DayTrade].[udf_GetTotalLast90Days] 
( 
    @Date  datetime 
) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT Acct, Sum(AGGCnt) As AGGCnt, AGGNumb 
    FROM  DT.vwGet_CountHist 
    WHERE (PostDate >= @Date - 90) AND (PostDate <= @Date) 
    GROUP BY Acct, AGGNumb 
) 

deuxième fonction

ALTER FUNCTION [DayTrade].[udf_GetTotalLast90Days] 
( 
    @Date  datetime 
) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT  Acct, Sum(AGGCnt) As AGGCnt, Max(AGGNumb) As AGGNumb 
    FROM  DT.vwGet_CountHist 
    WHERE (PostDate >= @Date - 90) AND (PostDate <= @Date) 
    GROUP BY Acct 
) 

Comme vous pouvez voir la différence dans la deuxième est que je suis le Max(AGGNumb) As AGGNumb et ajoutais un retrait du groupe Bys. J'ai essayé de changer cela et de passer une variable supplémentaire @Agg qui était un champ de bit pour ensuite utiliser un IF statement pour choisir quelle fonction utiliser mais je n'ai pas pu le faire fonctionner.

Des suggestions sur la façon de consolider ces deux fonctions en 1?

Merci

Répondre

4

Un paramètre sera NULL, donc WHERE échoue pour une seule clause.

ALTER FUNCTION [DayTrade].[udf_GetTotalLast90Days] 
( 
    @Date  datetime = NULL, 
    @BusinessDate = NULL 
) 
RETURNS TABLE AS RETURN 
(
    SELECT Acct, Sum(AGGCnt) As AGGCnt, AGGNumb 
    FROM  DT.vwGet_CountHist 
    WHERE (PostDate >= @Date - 90) AND (PostDate <= @Date) 
    GROUP BY Acct, AGGNumb 
    UNION ALL 
    SELECT  Acct, Sum(AGGCnt) As AGGCnt, Max(AGGNumb) As AGGNumb 
    FROM  DT.vwGet_CountHist 
    WHERE (PostDate >= @BusinessDate - 90) AND (PostDate <= @BusinessDate) 
    GROUP BY Acct 
) 
+0

J'ai mis à jour le code ci-dessus, c'est @Date sur les deux où les clauses pas @businessDate, cela fait-il une différence? – Taryn

+0

+1. Cela semble meilleur que ma méthode – Simon

+0

@bluefeet: vous avez toujours besoin d'une variable de contrôle pour décider quelle requête exécuter. Vous pouvez aussi bien avoir 2 paramètres pour contrôler cela – gbn

0

Vous pouvez passer un paramètre de contrôle à la fonction comme si (non testé)

EDIT: ajout imbriquée SELECT

ALTER FUNCTION [DayTrade].[udf_GetTotalLast90Days] 
    (  @Date  datetime, @GetMax tinyint) 
    RETURNS TABLE AS RETURN 
    ( SELECT  Acct, Sum(AGGCnt) As AGGCnt, 
    CASE @GetMax = 1 THEN (SELECT Max(AGGNumb) FROM DT.vwGet_CountList WHERE (...)GROUP BY Max(aGGNumb)) 
ELSE (SELECT AGGNumb FROM DT.vwGet_CountList WHERE (...)) AS AGGNum END 
     FROM  DT.vwGet_CountHist  
     WHERE (PostDate >= @BusinessDate - 90) AND (PostDate <= @BusinessDate)  
     GROUP BY Acct) 

Si cela ne fonctionne pas, vous devrez peut-être mettre en œuvre les deux SELECT séparément, mais dans la même procédure - je sais ne résout pas vraiment le problème, mais il faudra seulement 1 procédure.

+0

ce faisant de cette façon, je reçois une erreur de ne pas avoir le AGGNumb dans le groupe par. Je n'en ai besoin dans le groupe que lorsque je n'utilise pas le Max(). – Taryn

+0

Ce n'est pas la manière la plus efficace d'utiliser imbriqué select – Simon

+0

C'est ce que j'essayais de faire, était les implémenter tous les deux dans la même fonction mais je ne pouvais pas comprendre comment faire cela. – Taryn

0

Je pense, cela devrait fonctionner:

ALTER FUNCTION [DayTrade].[udf_GetTotalLast90Days] 
( 
    @Date  datetime, 
    @Agg  bit 
) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT Acct, Sum(AGGCnt) As AGGCnt, MAX(AGGNumb) AS AGGNumb 
    FROM  DT.vwGet_CountHist 
    WHERE (PostDate >= @Date - 90) AND (PostDate <= @Date) 
    GROUP BY Acct, AGGNumb * (1 - @Agg) 
) 

Lorsque @Agg = 1, il regroupera par Acct que, lorsque @Agg = 0, puis par Acct, AGGNumb.

1

Cela semble efficace:

CREATE FUNCTION DayTrade.udf_GetTotalLast90Days 
     ( 
     @Date  DATE, 
     @Summary BIT 
     ) 
RETURNS 
TABLE 
AS 
RETURN SELECT Acct, 
       AGGCnt = SUM(AGGCnt), 
       AGGNumb = MAX(AGGNumb) 
     FROM DT.vwGet_CountHist 
     WHERE PostDate BETWEEN DATEADD(DAY, -90, @Date) AND @Date 
     GROUP BY 
       GROUPING SETS ((Acct), (Acct, AGGNumb)) 
     HAVING GROUPING_ID(AGGNumb) = @Summary 
     ; 
GO