【问题标题】:SQL Server : Segregate data into dynamic bucketsSQL Server:将数据分离到动态存储桶中
【发布时间】:2017-05-23 09:14:53
【问题描述】:

请帮助我使用可以将数据动态存储到范围中的 SQL Server 查询。

这是我的源数据:

价值 ======= 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

预期输出:

价值排名 ============== 45 1 (此范围内的平均值为 45) 33.5 2 33.1 2 33 2 32.8 2 (平均值为 33.1 - (-10%) 29.79 到 36.41 (+10%) 范围内的任何值都应为 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% 的数据集

【问题讨论】:

  • 你的问题是什么?
  • 我已经编辑了这个问题。现在清楚了吗?
  • 我根据下方的评论在您的帖子中添加了更多信息。请使用更多示例详细信息进一步编辑您的帖子 - 即平均值是什么,以及几个存储桶的示例计算

标签: sql sql-server rank dense-rank


【解决方案1】:

首先将该值转换为具有 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

【讨论】:

    【解决方案2】:

    这是一种方法:

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

    使用dense_rank,但在order by 子句中指定您的存储桶。 (我假设这就是它适用于您的示例数据的方式)

    【讨论】:

    • 如果 val = 30.5,那么 rank 将是 2 与您的查询。但我认为,如果val = 30.5,OP 需要 rank = 3。
    • 它不能完全解决问题.. Val/10 可能不适用于我作为分组子句,因为在 20 到 30 之间可能有两个集群。我有办法用集群值说10%的差异?我已更改问题以添加其他数据集
    • 您可以按顺序更改分桶逻辑。除以 4,你得到不同数量的桶。您能否在问题中指定您预期的存储桶/逻辑,而不是让我们猜测?
    • 我的逻辑是识别数据中的那些集群并对其进行排名。我们的数据可能从几百到一百万不等。聚类是与平均值相差 10% 的数据集
    • 我将编辑您的帖子并添加这个重要的业务规则。下次请在问题中解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    相关资源
    最近更新 更多