问题
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.
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
I am attempting to get this result based on the following query.
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
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.
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.
回答1:
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
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.
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.
回答2:
I think you're looking for:
SUM(TotProfit) OVER (PARTITION by AssetStyle, ValuationDate) /
SUM(TotACB) OVER (PARTITION by AssetStyle, ValuationDate)
That is, sum your numerator and denominator independently, then divide those sums.
来源:https://stackoverflow.com/questions/33881918/sql-partition-data-within-and-outside-of-a-common-table-expression