SQL Server:将数据分离到动态存储桶中

时间:2017-01-09 06:51:29

标签: sql sql-server rank dense-rank

请帮我一个SQL Server查询,它可以动态地将数据存储到范围内。

这是我的源数据:

Value
=======
45

33.5
33.1
33
32.8

25.3
25.2
25.1
25

21.3
21.2
21.1
20.9

12.3
12.2
12.15
12.1
12
11.8

预期产出:

Value  Rank
=============
45        1
(mean value in this range is 45)

33.5      2
33.1      2
33        2
32.8      2
(mean value is 33.1 - any value in the range (-10%) 29.79 to 36.41 (+10%) should be given a rank of 2)

25.3      3
25.2      3
25.1      3
25        3

21.3      4
21.2      4
21.1      4
20.9      4

12.3      5
12.2      5
12.15     5
12.1      5
12        5
11.8      5

DENSE,RANK和NTILE似乎没有给我这样的排名。该范围是动态的,不是早先知道的。任何帮助高度赞赏。

分组规则是:

每个存储桶包含的数据集与平均值的差异为10%

2 个答案:

答案 0 :(得分:1)

这是一种方式:

select val, dense_rank() over (order by cast(val/10 as int) desc) ntile 
from yourtable

使用dense_rank但在order by子句中指定您的存储桶。 (我假设这是你的样本数据的工作方式)

答案 1 :(得分:0)

首先将值转换为具有2位小数的数字 然后,根据小数点后的第一个数字,使用CASE表达式执行FLOORROUND函数。
然后使用DENSE_RANK函数根据舍入值给出排名。

<强>查询

select z.[Value], dense_rank() over(order by z.[val_rounded] desc) as [Rank] from(
    select t.[Value],
    case when substring(t.[Value2], charindex('.', t.[Value2], 1) + 1, 1) > 5 
    then round(t.[Value], 0) else floor(t.[Value]) end as [val_rounded] from(
        select [Value], cast((cast([Value]as decimal(6, 2))) as varchar(50)) as [Value2]
        from [your_table_name]
    )t
)z;

Demo