根据子组中的几列计算百分比

时间:2017-03-01 21:50:26

标签: sql sql-server

我有一张桌子(让我们称之为Table A),如下所示:

ID        Device        Clicks
1         A             10
1         B             10
2         A             1
2         C             19

我想在上面Table B建立一个表格(我们称之为A),如下所示:

ID        Device        Clicks        Percentage
1         A             10            50
1         B             10            50
2         A             1             5
2         C             19            95

再次从Table B开始,我想得出Table C每个Updated Device的{​​{1}}列都会带有ID的名称仅当Device为> = 95%时才列。如果每个Percentage的{​​{1}}之间的百分比分配是其他任何内容,我们只需将Devices设置为ID即可。例如,使用UpdatedDevice中的数据,我们会得到如下所示的Others

Table B

我想知道是否有办法一次性使用高级SQL窗口/分析功能而不是生成中间表。

提前感谢您的回答!

2 个答案:

答案 0 :(得分:4)

select 
    Id
  , Device
  , Clicks
  , Percentage 
  , UpdatedDevice = isnull(max(UpdatedDevice) over (partition by Id),'Others')
from (
  select *
    , Percentage = convert(int,(clicks / sum(clicks+.0) over (partition by Id))*100)
    , UpdatedDevice = case 
        when (clicks / sum(clicks+.0) over (partition by Id)) >= .95
          then Device
        end
  from t
) as cte

测试设置:http://rextester.com/XKBNO39353

返回:

+----+--------+--------+------------+---------------+
| Id | Device | Clicks | Percentage | UpdatedDevice |
+----+--------+--------+------------+---------------+
|  1 | A      |     10 | 50         | Others        |
|  1 | B      |     10 | 50         | Others        |
|  2 | A      |      1 | 5          | C             |
|  2 | C      |     19 | 95         | C             |
+----+--------+--------+------------+---------------+

答案 1 :(得分:1)

只是为了踢,你可以在没有子查询的情况下做到这一点:

select t.*,
       clicks * 1.0 / sum(clicks) over (partition by id) as ratio,  -- you an convert to a percentage
       (case when max(clicks) over (partition by id) >= 0.95 * sum(clicks) over (partition by device)
             then first_value(device) over (partition by id order by clicks desc)
             else 'Others'
        end) as UpdatedDevice             
from t;

计算UpdatedDevice的关键思想是最大值是满足95%规则的设备。当然还有first_value()