【问题标题】:Select statement that divides arbitrary data into buckets that sum up to a specific value将任意数据划分为总和为特定值的桶的 Select 语句
【发布时间】:2016-05-28 17:52:38
【问题描述】:

Oracle 数据库中是否有一种方法可以将一定数量的钱分成几个等份的桶,然后使用单个 SELECT 语句确保钱的总和等于初始金额?

也许是聚合函数的一些奇特组合?

例如:我们有 100 美元的金额和 3 个时间桶。我需要查询结果类似于

(33.33, 33.33, 33.34)

所以最后一个值平衡了那里的一切。

示例数据:

  1. 期间开始数据 01/01/2015
  2. 期间结束日期 01/01/2016
  3. 总体积121吨

我需要 SQL 命令在所有月份中输出平均分布的总交易量,所以我在最后得到:

1 月 - 10 日 2 月 - 10 日 ... 11 月 - 10 日 12 月 - 11 日

【问题讨论】:

  • 你能提供样本数据和想要的结果吗?
  • 请解释逻辑。您需要对存储桶进行 INTEGER 分配吗?您的第一个示例将 100 分为 33.33、33.33 和 33.34,为什么第二个示例不将 121 吨分为 10.08、10.08、...、10.08,最后一个 10.12 来构成 121.00 的总数?为什么这里是整数,而不是第一个例子?那么,假设你真的想要整数——所有的“超额”(额外的东西)应该去最后一个桶,还是均匀地分布在最后几个桶上?如果你有 122 个而不是 121 个,那么 11 个月应该得到 10 个,最后一个 12 个,还是应该前 10 个得到 10 个,最后两个 11 个?

标签: sql oracle


【解决方案1】:

如果你有一个时间段表,那么只需使用窗口函数:

select 100.0 / count(*) over () as bucket_amount
from buckets b;

请注意,这对所有三个都给出了相等的数量,因此没有 33.34。它可以为此目的进行调整,但您确实需要提供示例数据和所需的结果。

【讨论】:

    【解决方案2】:

    查询

    SELECT month,
           FLOOR( lvl * volume / num_months ) -
             FLOOR( (lvl - 1) * volume / num_months ) AS bucket
    FROM   ( 
      SELECT     volume,
                 FLOOR( MONTHS_BETWEEN( end_month, start_month ) ) AS num_months,
                 ADD_MONTHS( start_month, LEVEL - 1 ) AS month,
                 LEVEL AS lvl
      FROM       (
        SELECT 121 AS volume,
               DATE '2015-01-01' AS start_month,
               DATE '2016-01-01' AS end_month
        FROM   DUAL
      )
      CONNECT BY ADD_MONTHS( start_month, LEVEL - 1 ) < end_month
    );
    

    输出

    MONTH                   BUCKET
    ------------------- ----------
    2015-01-01 00:00:00         10 
    2015-02-01 00:00:00         10 
    2015-03-01 00:00:00         10 
    2015-04-01 00:00:00         10 
    2015-05-01 00:00:00         10 
    2015-06-01 00:00:00         10 
    2015-07-01 00:00:00         10 
    2015-08-01 00:00:00         10 
    2015-09-01 00:00:00         10 
    2015-10-01 00:00:00         10 
    2015-11-01 00:00:00         10 
    2015-12-01 00:00:00         11 
    

    【讨论】:

    • 如果将音量从 121 更改为 122,则 6 月将变为 11,12 月将变为 11。这似乎与 OP 的要求不一致(但是,正如我所说,要求并不完全清楚在对原始问题的评论中 - 在他/她首先澄清要求之前,我会坚持任何额外的工作)。
    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多