财务表的SecurityID,FundID和Value已按FundID分组,并在每个FundID中排名/排序
它可能看起来像这样(想象数百或记录):
+------+------------+--------+-------+
| Rank | SecurityID | FundID | Value |
+------+------------+--------+-------+
| 1 | 23 | A | 5 |
| 2 | 43 | A | 4 |
| 3 | 44 | A | 3 |
| 1 | 72 | B | 8 |
| 2 | 75 | B | 7 |
| 3 | 76 | B | 2 |
| 1 | 83 | C | 5 |
+------+------------+--------+-------+
目标是获得每种基金类型中前20%的证券。然后从该20%得到值的总和。例如,如果基金类型A中有10个证券,那么我想总结前2个记录中的值。答案是9.
SQL可能如下所示:
SELECT SUM(Value) as TopTwenty, FundID
FROM @FinanceTable
WHERE Rank <= ((SELECT COUNT(*)
FROM @FinanceTable WHERE FundID = 1) * .20)
GROUP BY FundID
上述查询适用于FundID = 1.但是,我不想指定“Where FundID = 1”。相反,我希望它为所有FundID运行此查询。这是我难倒的部分。我想我可以用光标做到这一点。但有没有办法在没有光标的情况下这样做?
谢谢!
答案 0 :(得分:2)
您可以使用窗口函数count(*)
来获取每个基金的总行数。然后使用where
子句进行过滤:
select FundID, sum(value)
from (select ft.*, count(*) over (partition by FundId) as cnt
from @FinanceTable ft
) ft
where rank <= 0.2*cnt
group by FundId;
答案 1 :(得分:1)
;with FundCounts As
(
Select FundID, Count(*) * 0.2 As TopTwentyCount
From Finance
Group By FundID
)
select F.FundID, Sum(Value) as TopTwentyValueSum
from Finance F
inner join FundCounts FC on F.FundID = FC.FundID
where F.[Rank] <= FC.TopTwentyCount
group by F.FundID