【问题标题】:Use sum function in calculated column在计算列中使用 sum 函数
【发布时间】:2019-07-29 15:16:04
【问题描述】:

是否可以在计算列中使用求和函数? 如果是,我想创建一个计算列,计算同一个表中日期小于此条目日期的列的总和。这可能吗? 最后,这是否会优化下面示例视图中对该值的重复调用?

SELECT ProductGroup, SalesDate, (
  SELECT SUM(Sales)
  FROM SomeList
  WHERE (ProductGroup= KVU.ProductGroup) AND (SalesDate<= KVU.SalesDate)) AS cumulated
FROM SomeList AS KVU

【问题讨论】:

    标签: tsql ssms calculated-columns


    【解决方案1】:

    是否可以在计算列中使用求和函数?

    是的,可以为计算列使用scalar valued function(标量 UDF),但这将是一场灾难。对计算列使用标量 UDF 会破坏性能。添加访问数据的标量 UDF(此处需要)会使事情变得更糟。

    在我看来,您只需要一个好的老式索引来加快速度。首先是一些示例数据:

    IF OBJECT_ID('dbo.somelist','U')    IS NOT NULL DROP TABLE dbo.somelist;
    GO
    
    CREATE TABLE dbo.somelist
    (
      ProductGroup INT           NOT NULL,
      [Month]      TINYINT       NOT NULL CHECK ([Month] <= 12),
      Sales        DECIMAL(10,2) NOT NULL
    );
    
    INSERT dbo.somelist 
    VALUES (1,1,22),(2,1,45),(2,1,25),(2,1,19),(1,2,100),(1,2,200),(2,2,50.55);
    

    以及正确的索引:

    CREATE NONCLUSTERED INDEX nc_somelist ON dbo.somelist(ProductGroup,[Month])
    INCLUDE (Sales);
    

    有了这个索引,这个查询将非常有效:

    SELECT   s.ProductGroup, s.[Month], SUM(s.Sales)
    FROM     dbo.somelist AS s
    GROUP BY s.ProductGroup, s.[Month];
    

    如果您需要按月和产品组获取 COUNT,您可以像这样创建索引视图:

    CREATE VIEW dbo.vw_somelist WITH SCHEMABINDING AS 
    SELECT   s.ProductGroup, s.[Month], TotalSales = COUNT_BIG(*)
    FROM     dbo.somelist AS s
    GROUP BY s.ProductGroup, s.[Month];
    GO
    
    CREATE UNIQUE CLUSTERED INDEX uq_cl__vw_somelist ON dbo.vw_somelist(ProductGroup, [Month]);
    

    一旦建立索引视图,您的 COUNT 将被预先聚合。但是,您不能在索引视图中包含 SUM。

    【讨论】:

    • 嗨艾伦,谢谢你的回答。正如您所描述的,我已经有一个索引,但是性能非常低。我没有尝试索引视图,因为我认为这是不可能的。您可以更改您的视图示例以匹配我的选择语句吗?
    • 我在示例中更改了月份至今,因为月份具有误导性
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 2013-10-07
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多