【问题标题】:If Statement in Table valued Function表值函数中的 If 语句
【发布时间】:2011-03-04 20:11:40
【问题描述】:

我有 2 个非常相似的表值函数,唯一的区别是我需要在第二个函数上额外调用一个 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 来选择要使用的函数,但我无法让它工作。

关于如何将这两个功能合二为一有什么建议吗?

谢谢

【问题讨论】:

    标签: sql-server user-defined-functions


    【解决方案1】:

    一个参数将为 NULL,因此 WHERE 仅针对一个子句失败。

    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
    )
    

    【讨论】:

    • 我更新了上面的代码,两个where子句都是@Date而不是@businessDate,这有什么不同吗?
    • @bluefeet:您仍然需要一个控制变量来决定运行哪个查询。你也可以有 2 个参数来控制这个
    • 我想我仍然对此感到困惑。这是一个参数@Date,然后我知道我应该添加第二个参数来告诉函数使用哪个select语句,但是当我尝试这样做时遇到了麻烦。
    • 我使用了一种叫做@Max 的东西,然后使用了一个If 语句来表示-如果@Max = true,则使用带有Max() 的查询,如果它为false,则使用另一个。类似于可以在存储过程中使用的东西。这些表值函数对我来说是新的,我似乎无法弄清楚如何让它决定运行哪个查询。
    【解决方案2】:

    您可以像这样将控制参数传递给函数(未经测试)

    编辑:添加嵌套 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 个过程。

    【讨论】:

    • 这样做,我收到一个错误,提示 Group By 中没有 AGGNumb。当我不使用 Max() 时,我只需要在 Group By 中使用它。
    • 这不是使用嵌套选择最有效的方法
    • 这就是我想要做的,在同一个函数中实现它们,但我不知道该怎么做。
    【解决方案3】:

    我认为,这应该可行:

    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 分组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      相关资源
      最近更新 更多