代码之家  ›  专栏  ›  技术社区  ›  JeffO

联合或使用流控制逻辑来确定要报告的表

  •  0
  • JeffO  · 技术社区  · 17 年前

    我正在使用一个第三方应用程序,在那里我无法更改表格。我们使用额外的日期时间列“AsOfDate”构建了自定义匹配的“Monthly”表,在该列中,我们在月底转储数据,并用该月最后一天的日期标记这些数据。

    我希望能够创建一个单独的存储过程(应用程序的设计要求视图或存储过程作为所有报告的源),并使用一个参数,该参数将使用当前数据表(参数可能为NULL或=今天的日期),或者使用月末表并按月末日期进行筛选。这样,我就有了一个报告,用户可以在其中使用当前数据或特定月末的数据。

    你更喜欢哪一种(以及为什么)抱歉,这还没有完全编码

    解决方案#1联合查询

    Create Proc Balance_Report (@AsOfDate)
    AS
    
    Select Column1
    From
        (Select GetDate() as AsOfDate
           , Column1 
         From Current.Balance
        Union 
        Select AsOfDate
           , Column1 From MonthEnd.Balance
        ) AS All_Balances
    Where All_Balances.AsOfDate = @AsOfDate
    

    解决方案#2使用If语句选择表

    Create Proc Balance_Report (@AsOfDate)
    AS
    
    If @AsOfDate IS NULL or @AsOfDate = GetDate()
       Select GetDate() as AsOfDate
           , Column1 
         From Current.Balance
    Else
        Select AsOfDate
           , Column1 From MonthEnd.Balance
        Where AsOfDate = @AsOfDate
    

    同样,这并没有完全编码,而且有点数据库无关(但它是SQL Server 2005)。

    编辑:使用单独的存储过程对解决方案#2进行更改

    Create Proc Balance_Report (@AsOfDate)
    AS
    
    If @AsOfDate IS NULL or @AsOfDate = GetDate()
       Exec Current_Balance_Date -- no param necessary
    Else
        exec MonthEnd_Balance_Date @AsOfDate
    
    2 回复  |  直到 13 年前
        1
  •  1
  •   Tom H zenazn    17 年前

    第二种方法可能会更快。如果你要使用分区视图,那么你可以设置约束,这样优化的人就会知道忽略选择中的一个或多个表,你就能获得相同的性能。这也可以让你将所有的逻辑保存在一个语句中,而不必让两个语句保持同步。根据SELECT语句的复杂程度,这对您来说可能是也可能不是问题。

    不过,有一件事要记住,如果你使用第二种方法,一定要将你的存储过程标记为WITH(RECOMPILE)(我不记得括号是否是必需的——检查语法)。这样,优化器将根据需要执行IF语句的哪个分支来创建新的查询计划。

        2
  •  1
  •   tvanfosson    17 年前

    我更喜欢非工会解决方案。从单个表中选择总是比进行联合并从联合中选择单个表的数据更快。