公共表表达式内外的SQL分区数据 [英] SQL Partition data within and outside of a Common Table Expression

查看:62
本文介绍了公共表表达式内外的SQL分区数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SQL Server 2012,我具有以下示例结果集。带有Tot前缀的列是从左侧的列派生的。

I am using SQL Server 2012 I have the following sample result set. The columns with the Tot Prefix are derived from the columns to the left.

我想做的是给定日期和给定AssetStyle的数据分区。基于此标准,我要对利润和ACB求和。然后,我想将这两个总和的结果除以总的返回数。示例数据如下。

What I am trying to do is partition data for a given date, and a given AssetStyle. Based on this criteria I want to sum profit and sum ACB. I then want to divide the results of these two sums for a total return number. The sample data is below.

ValuationDate   CustodianaccountNum AssetStyle  AssetClass  Profit  ACB NetReturn   TotProfit   TotACB  TotReturn
3/31/2007   1111    All Cap US All Cap  2552.55337  1069804.43  0.002386    719511.4487 7859959.87  0.091541364
3/31/2007   2222    All Cap US All Cap  1085.121285 1547961.89  0.000701    719511.4487 7859959.87  0.091541364
3/31/2007   3333    All Cap US All Cap  715873.774  3298000 0.217063    719511.4487 7859959.87  0.091541364
3/31/2007   4444    All Cap US All Cap  0   1944193.55  0   719511.4487 7859959.87  0.091541364
4/30/2007   1111    All Cap US All Cap  1374.387675 554859.78   0.002477    404343.9809 5803741.618 0.069669535
4/30/2007   2222    All Cap US All Cap  8041.548001 1038959.69  0.00774 404343.9809 5803741.618 0.069669535
4/30/2007   3333    All Cap US All Cap  -714.739726 554922.1475 -0.001288   404343.9809 5803741.618 0.069669535
4/30/2007   4444    All Cap US All Cap  395642.785  3655000 0.108247    404343.9809 5803741.618 0.069669535
3/31/2008   1111    Alt. Investment Strategies  Alternative Investments -6701.16054 1445773.579 -0.004635   -46461.95138    2709953.979 -0.017144923
3/31/2008   2222    Alt. Investment Strategies  Alternative Investments -2859.33957 37854.99999 -0.075534   -46461.95138    2709953.979 -0.017144923
3/31/2008   3333    Alt. Investment Strategies  Alternative Investments 0   247481.1    0   -46461.95138    2709953.979 -0.017144923
3/31/2008   4444    Alt. Investment Strategies  Alternative Investments -36901.45127    978844.3    -0.037699   -46461.95138    2709953.979 -0.017144923

我正在尝试获得此结果

WITH DATA AS
(
SELECT 
  ValuationDate, 
  CustodianaccountNum,
  AssetStyle, 
  AssetClass, 
  Profit, 
  ACB, 
  NetReturn, 
  SUM(Profit) OVER  (PARTITION by  AssetStyle, ValuationDate) AS TotProfit,
  SUM(ACB) OVER  (PARTITION by  AssetStyle, ValuationDate) AS TotACB
FROM 
  [PWM_Performance].[dbo].[BucketPerformance2]
)
SELECT 
  *, 
  SUM(TotProfit/TotACB) OVER  (PARTITION by  AssetStyle, ValuationDate) AS TotReturn
FROM data
  WHERE Totacb > 1
  ORDER BY AssetStyle, ValuationDate

我正在获得TotProfit和totACB的预期结果,但是我没有为TotReturn获得正确的结果。示例数据显示了正确的结果,但是我得到的值不是我在分区语句中指示的数据子集的总和。

I am getting the expected result for TotProfit and totACB, but I am not getting the correct result for TotReturn. The sample data shows the correct result but I am getting different values that aren't the sum of the data subsets I have indicated in my partition statement.

我正在使用CTE,因为我认为我无法从前面的两个利润和ACB的总和中得出计算结果。

I am using a CTE because I don't think I can derive a calculation from the two preceding derived sums of profit and ACB.

推荐答案

WITH DATA AS
(
SELECT 
  ValuationDate, 
  CustodianaccountNum,
  AssetStyle, 
  AssetClass, 
  Profit, 
  ACB, 
  NetReturn, 
  SUM(Profit) OVER (PARTITION BY  AssetStyle, ValuationDate) AS TotProfit,
  SUM(ACB) OVER (PARTITION BY  AssetStyle, ValuationDate) AS TotACB
FROM PWM_Performance.dbo.BucketPerformance2
)
SELECT 
  *, 
  TotProfit / TotACB AS TotReturn
FROM data
WHERE TotACB > 1
ORDER BY AssetStyle, ValuationDate

您已经掌握了正确的分子和分母。样式和日期分区分别具有四行,每行均具有相同的值。因此,当您第二次对相同的分区求和时,它只是一遍又一遍地添加相同的比率:除法是完成计算所需的全部。而且,如果您没有对 TotACB 进行过滤,则可以取消CTE。

You already had the right numerator and denominator in hand. The partitions in style and date each have four rows all having the same values. So when you summed over identical partitions a second time it was simply adding the same ratio over and over: division was all you needed in order to finish the calculation. And had you not been filtering on TotACB you could have eliminated the CTE.

另一个答案在以下方面起作用代数,但它正在做额外的工作。作为示例,它不仅要直接吐出1/2,还必须算出(1 + 1 + 1 + 1)/(2 + 2 + 2 + 2)。性能可能最终成为一个因素,考虑到浮点的性质,结果中肯定会有差异的可能。

The other answer works in terms of the algebra but it's doing extra work. Instead of just directly spitting out 1/2, as an example, it has to work out (1+1+1+1) / (2+2+2+2). Performance might eventually be a factor and there is definitely some potential for differences in the result given the nature of floating point.

这篇关于公共表表达式内外的SQL分区数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆