1
col1    col2
b   5
b   10
b   20
b   30
b   200
b   300

从 mytable 中选择前 50 个百分比 col2 给出

col2
5
10
20

而实际的 50% 不同

col1 col2   Total(of col2)   div(col2/total)    CumulativeAddition  %
b   5           565                 0.01            0.01            1%
b   10          565                 0.02            0.03            3%
b   20          565                 0.04            0.06            6%
b   30          565                 0.05            0.12            12%
b   200         565                 0.35            0.47            47%
b   300         565                 0.53            1.00            100%

如您所见

5   1%
10  3%
20  6%
30  12%
200 47%

我是否使用了正确的 SQL 函数?

4

2 回答 2

3

在 SQL Server 2012 中,您可以使用窗口函数来计算运行总和。累积百分比是运行总和除以整个表的总和。

select  *
from    (
        select  *
        ,       100.0 * sum(col2) over (order by col2) / sum(col2) over () 
                    as perc
        from    dbo.YourTable
        ) SubQueryAlias
where   perc <= 50.0

子查询是必需的,因为 SQL Server 不允许在where子句中使用窗口函数。

SQL Fiddle 的示例。


对于旧版本的 SQL Server,计算运行总和需要更多的工作。如果您有联系col2,则必须提供一种区分它们的方法。

select  *
from    (
        select  cur.col1
        ,       cur.col2
        ,       100.0 * sum(running.col2) / total.total as perc
        from    dbo.YourTable cur
        join    (
                select  col2
                from    dbo.YourTable prev
                ) running
        on      running.col2 < cur.col2
        cross join
                (
                select  sum(col2) as total
                from    YourTable
                ) total
        group by
                cur.col1
        ,       cur.col2      
        ,       total.total
        ) SubQueryAlias
where   perc <= 50.0

SQL Fiddle 的示例。

于 2013-05-21T09:25:16.637 回答
1

如前所述,top语法并不能满足您的要求。

您需要一个累计金额。唉,这在 SQL Server 2012 中受到直接支持,但在 SQL Server 2008 中不支持。

为了可读性,我更喜欢使用相关子查询来获取累积和。查询的其余部分只是算术:

select col1, col2, TotalCol2, CumSumCol2,
       CumSumCol2 / cast(TotalCol2 as float) as CumPercent
from (select col1, col2,
             sum(col2) over (partition by col1) as TotalCol2,
             (select sum(col2) from mytable t2 where t2.col1 = t.col1 and t2.col2 <= t.col2
             ) as CumSumCol2
      from mytable t
     ) t
where CumSumCol2 / cast(TotalCol2 as float) < 0.5
于 2013-05-21T10:37:02.153 回答