【问题标题】:SQL - get sum of values from top 20 percent per categorySQL - 从每个类别的前 20% 中获取值的总和
【发布时间】:2014-03-04 23:29:31
【问题描述】:

这个很棘手。

Finance 表的 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 运行此查询。这是我被难住的部分。我想我可以使用游标来做到这一点。但是有没有办法在没有光标的情况下做到这一点?

谢谢!

【问题讨论】:

  • 你能改进一下标题吗?我怀疑有人会搜索“棘手的 SQL Server 查询”。他们可能会搜索“在 SQL Server 中获取行的百分比并对它们的值求和”之类的。

标签: sql sql-server sql-server-2008 tsql


【解决方案1】:

您可以使用窗口函数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;

【讨论】:

  • 戈登,谢谢。但是我遇到了一些问题 ft.* ???有人给了你一个赞成票,所以它可能有效。我最终在下面使用了@amit_g 的答案。
  • @nanonerd 。 . .它只是子查询中缺少的别名。
【解决方案2】:
;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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    相关资源
    最近更新 更多