sql - 存储桶中的数据分布 - Oracle 11g
问题描述
我有一个有两列的表BRANCH
,ACTIVITIES
其中BRANCH
是位置的唯一 id,并且ACTIVITIES
是属于各自的记录数BRANCH
。这些记录将分布在 5 个存储桶中,所有存储桶都应包含几乎相等数量的记录。(无论差异是否为 +/-1000)
挑战是如果在一个桶中选择了一个分支,那么同一分支的所有活动也将在同一个桶中被选择,换句话说,属于一个的活动的数量BRANCH
不能被拆分。让我们举一个非常简单的例子,这样我就可以解释我想要实现的目标
Total Branches=10
Total Number of activities (records) = 55,000
Average (total activities/total buckets) = 11,000
样本数据
分配后
所有存储桶都包含 11,000 条记录,但是当我们查看真实数据时,事情并不是那么简单。
请所有 Oracle 查询大师对此进行调查。您的专家意见将不胜感激。
解决方案
不幸的是,这是一个装箱问题,一个“完美”的解决方案需要——本质上——搜索所有可能的桶分配,然后选择“最好的”一个。而这样的方法并不真正适合 SQL。
但是,对于“足够好”的解决方案,类似循环方法的方法通常效果很好。只需从最大到最小枚举分支并将它们分配给存储桶:
select a.branch,
1 + mod(seqnum, 5) as bucket
from (select a.branch, count(*) as cnt,
row_number() over (order by count(*)) desc as seqnum
from activities a
group by a.branch
) a;
由于排序,这通常会创建不同大小的桶。因此,稍有变化将桶分配为 1-2-3-4-5-5-4-3-2-1:
select a.branch,
(case when mod(seqnum, 10) in (0, 9) then 1
when mod(seqnum, 10) in (1, 8) then 2
when mod(seqnum, 10) in (2, 7) then 3
when mod(seqnum, 10) in (3, 6) then 4
when mod(seqnum, 10) in (4, 5) then 5
end) as bucket
from (select a.branch, count(*) as cnt,
row_number() over (order by count(*)) desc as seqnum
from activities a
group by a.branch
) a;
推荐阅读
- java - 单击按钮后对 Firebase Recyclerview 进行排序
- angular - 从 Rxjs WebSocket 主题调用返回 Observable 数组
- python - 如何使用三重算法使用 56 个字符的键对字符串进行编码?
- confluent-platform - KSQL 'SELECT *' 查询需要 10 秒才能开始返回任何结果
- json - 找不到 io.circe.generic.decoding.DerivedDecoder[Staff] 类型的惰性隐式值
- java - 如何使应用程序成为共享的选项?
- python - 混合 Numpy 向量化和普通 Python
- apache-spark - 发送结果 RpcResponse / 关闭连接时出错 - Datastax Enterprise
- alexa - 是否需要在 S3 中公开音频文件才能在 alexa 设备上播放
- javascript - 如何在 ShadowDOM 中通过 id 查找元素?