0

我有以下查询,即使没有大量数据(约 3k 行),执行起来仍然有点慢,而且逻辑有点过头了——希望能得到一些帮助来优化查询甚至替代方法:

Select companypartnumber, (PartTotal + IsNull(Cum_Lower_Ranks, 0) ) / Sum(PartTotal) over() * 100 as Cum_PC_Of_Total
FROM PartSalesRankings PSRMain
Left join 
    (
        Select PSRTop.Item_Rank, Sum(PSRBelow.PartTotal) as Cum_Lower_Ranks
          from partSalesRankings PSRTop
          Left join PartSalesRankings PSRBelow on PSRBelow.Item_Rank < PSRTop.Item_Rank
         Group by PSRTop.Item_Rank 
    ) as PSRLowerCums on PSRLowerCums.Item_Rank = PSRMain.Item_Rank

PartSalesRankings 表简单地由 CompanyPartNumber(bigint) 组成,它是零件编号指定,PartTotal(decimal 38,5) 是总销售额,以及 Item_Rank(bigint) 是基于总销售额的项目排名。

我试图根据零件的百分位数将零件分类 - 所以“A”项目将是前 5%,“B”项目将是接下来的 15%,“C”项目将是较低的第 80 个百分位。我创建的视图运行良好,执行只需要近三秒钟,就我的目的而言,这非常慢。我将瓶颈缩小到上述查询 - 任何帮助将不胜感激。

4

1 回答 1

1

您遇到的问题是计算PartTotal. 如果您使用的是 SQL Server 2012,则可以执行以下操作:

select (case when ratio <= 0.05 then 'A'
             when ratio <= 0.20 then 'B'
             else 'C'
        end),
       t.*
from (select psr.companypartnumber,
             (sum(PartTotal) over (order by PartTotal) * 1.0 / sum(PartTotal) over ()) as ratio
      FROM PartSalesRankings psr
     ) t

SQL Server 2012 还具有百分位函数和其他早期版本中没有的函数。

在早期版本中,问题是如何有效地获得累积和。您的查询可能与可以在一个查询中完成的任何事情一样好。创建partSalesRankings时可以计算累计和吗?可以使用临时表吗?

于 2012-11-07T21:11:55.250 回答