Если оператор в табличной функции - PullRequest
1 голос
/ 04 марта 2011

У меня есть две табличные функции, которые очень похожи, с той лишь разницей, что мне нужен еще один вызов Max() для второй. Я хочу объединить их в одно, но не могу понять, как это сделать.

Первая функция

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
)

Вторая функция

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
)

Как вы можете видеть разницу во втором, я добавляю Max(AGGNumb) As AGGNumb и удаляю одного из Group Bys. Я попытался изменить это и передать дополнительную переменную @Agg, которая была битовым полем, чтобы затем использовать IF statement, чтобы выбрать, какую функцию использовать, но я не смог заставить ее работать.

Любые предложения о том, как объединить эти две функции в 1?

Спасибо

Ответы [ 4 ]

4 голосов
/ 04 марта 2011

Один параметр будет НЕДЕЙСТВИТЕЛЕН, поэтому, ГДЕ терпит неудачу только для одного предложения.

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
)
1 голос
/ 06 марта 2011

Это кажется эффективным:

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
0 голосов
/ 05 марта 2011

Я думаю, это должно работать:

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)
)

Когда @Agg = 1, он будет группироваться только по Acct, когда @Agg = 0, затем по Acct, AGGNumb.

0 голосов
/ 04 марта 2011

Вы можете передать управляющий параметр функции следующим образом (не проверено)

РЕДАКТИРОВАТЬ: добавлен вложенный 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 ) 

Если это не сработает, то вам может потребоваться реализовать два SELECT по отдельности, но в одной и той же процедуре - я знаю, что на самом деле это не решает проблему, но для этого потребуется только 1 процедура.

...