【问题标题】:Dividing a sum value into multiple rows due to field length constraint由于字段长度限制,将总和值分成多行
【发布时间】:2019-09-29 09:24:26
【问题描述】:

我正在通过汇总金额并将它们插入汇总表中来从一个非常大的表(超过 1 亿行)中迁移财务数据。当汇总金额(30 亿)大于汇总表中的字段可以容纳的数量(最多只能容纳 9.99 亿)时,我遇到了问题。更改字段大小不是一种选择,因为它需要更改过程。

我唯一的选择是将金额(超出大小限制的金额)分成较小的金额,以便将其插入表格中。

我遇到了这个SQL - I need to divide a total value into multiple rows in another table,除了我需要插入的行数是动态的之外,它很相似。

为简单起见,这就是源表的样子

account_table

acct_num   |      amt
-------------------------------
   101         125.00
   101         550.00
   101         650.00
   101         375.00
   101         475.00
   102          15.00
   103         325.00
   103         875.00
   104         200.00
   104         275.00

摘要记录如下

select acct_num, sum(amt) 
from account_table
group by acct_num

帐户摘要

acct_num   |      amt
-------------------------------
   101        2175.00
   102          15.00
   103        1200.00
   104         475.00

假设目标表中的最大值为 1000.00,则预期输出为

summary_table

acct_num   |      amt
-------------------------------
   101        1000.00
   101        1000.00
   101         175.00
   102          15.00
   103        1000.00
   103         200.00
   104         475.00

如何创建查询以获得预期结果?提前致谢。

【问题讨论】:

  • select acct_num, sum(amt) /10000。以后别忘了乘以 10000 来取回钱
  • 感谢您的回复,但我不明白上面的查询将如何根据源数据返回预期结果。

标签: sql oracle


【解决方案1】:

您需要一个数字表。如果您有几个值,您可以手动定义它。否则,您可能手头有一个或使用类似的逻辑:

with n as (
      select (rownum - 1) as n
      from account_table
      where rownum <= 10
     ),
     a as (
      select acct_num, sum(amt) as amt
      from account_table
      group by acct_num
     ) 
select acct_num,
       (case when (n.n + 1) * 1000 < amt then 1000
             else amt - n.n * 1000
        end) as amt
from a join
     n
     on n.n * 1000 < amt ;

【讨论】:

  • 非常感谢您的帮助。这就是我所需要的。

    结果实际上将所有内容都返回为 1000。我调整了条件以返回我需要的结果。 (当 (n.n + 1) * 1000 时的情况

【解决方案2】:

这些方面的变化可能会提供一些想法(使用您的 1,000 个样本数据):

WITH summary AS (

  SELECT acct_num
        ,TRUNC(SUM(amt) / 1000) AS times
        ,MOD(SUM(amt), 1000) AS remainder
    FROM account_table
    GROUP BY acct_num

), x(acct_num, times, remainder) AS (

  SELECT acct_num, times, remainder
    FROM summary

  UNION ALL

  SELECT s.acct_num, x.times - 1, s.remainder
    FROM summary s
        ,x
    WHERE s.acct_num = x.acct_num
      AND  x.times > 0

)
SELECT acct_num
      ,CASE WHEN times = 0 THEN remainder ELSE 1000 END AS amt
  FROM x
  ORDER BY acct_num, amt DESC

思路是先用div和模建一个汇总表:

ACCT_NUM    TIMES   REMAINDER
101         2       175
102         0       15
103         1       200
104         0       475

然后根据您想要的“次数”(即行)数对汇总表执行分层查询,其余部分额外查询。

ACCT_NUM    AMT
101         1000
101         1000
101         175
102         15
103         1000
103         200
104         475

【讨论】:

  • 谢谢。最初我就是这样开始的。我得到了次数和余数,不知道如何进行。我从未使用过分层查询,这非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多