使用持续时间(以月为单位)查询创建多个相等的交易量分布记录

问题描述 投票:0回答:2

Input Output Results

我有一个要求,我需要根据从链接表获取记录的持续时间将记录分布到多个记录中。

假设我的卷数为 100,链接表的持续时间为 20 个月,那么我的输出应该有 20 条记录,每条记录 5(100/20)。

有人可以帮我查询如何执行此 SQL。

sql oracle plsql
2个回答
0
投票

WITH 子句在这里只是为了生成一些示例数据,因此,它不是答案的一部分。
您可以连接产品列上的表,使用 LEVEL 限制迭代 <= DURATION, group the data and show the amount either as Min, Max or Avg of COST/DURATION rounded to two decimals. I put all of the data in the select list. Here is the complete code with the result.

 WITH
    t_duration AS
        (
            Select 'A' "PRODUCT", 10 "DURATION" From Dual Union All
            Select 'B' "PRODUCT",  6 "DURATION" From Dual Union All
            Select 'C' "PRODUCT",  4 "DURATION" From Dual 
        ),
    t_cost AS
        (
            Select 'A' "PRODUCT", 100 "COST" From Dual Union All
            Select 'B' "PRODUCT",  50 "COST" From Dual Union All
            Select 'C' "PRODUCT",  40 "COST" From Dual 
        )
SELECT
    LEVEL "MONTH_ORDER_NUMBER",
    d.PRODUCT "PRODUCT",
    d.DURATION "DURATION",
    c.COST "COST",
    Round(Avg(c.COST / d.DURATION), 2) "AVG_MONTHLY_AMOUNT",
    Round(Max(c.COST / d.DURATION), 2) "MAX_MONTHLY_AMOUNT",
    Round(Min(c.COST / d.DURATION), 2) "MIN_MONTHLY_AMOUNT"
FROM
    t_duration d
INNER JOIN
    t_cost c ON(c.PRODUCT = d.PRODUCT)
CONNECT BY LEVEL <= d.DURATION
GROUP BY 
    d.PRODUCT, d.DURATION, c.COST, LEVEL
ORDER BY 
    d.PRODUCT, LEVEL
--  
--  R e s u l t
--  
--  MONTH_ORDER_NUMBER PRODUCT   DURATION       COST AVG_MONTHLY_AMOUNT MAX_MONTHLY_AMOUNT MIN_MONTHLY_AMOUNT
--  ------------------ ------- ---------- ---------- ------------------ ------------------ ------------------
--                   1 A               10        100                 10                 10                 10 
--                   2 A               10        100                 10                 10                 10 
--                   3 A               10        100                 10                 10                 10 
--                   4 A               10        100                 10                 10                 10 
--                   5 A               10        100                 10                 10                 10 
--                   6 A               10        100                 10                 10                 10 
--                   7 A               10        100                 10                 10                 10 
--                   8 A               10        100                 10                 10                 10 
--                   9 A               10        100                 10                 10                 10 
--                  10 A               10        100                 10                 10                 10 
--                   1 B                6         50               8.33               8.33               8.33 
--                   2 B                6         50               8.33               8.33               8.33 
--                   3 B                6         50               8.33               8.33               8.33 
--                   4 B                6         50               8.33               8.33               8.33 
--                   5 B                6         50               8.33               8.33               8.33 
--                   6 B                6         50               8.33               8.33               8.33 
--                   1 C                4         40                 10                 10                 10 
--                   2 C                4         40                 10                 10                 10 
--                   3 C                4         40                 10                 10                 10 
--                   4 C                4         40                 10                 10                 10

0
投票

看起来好像

ntile
可以完成这项工作(至少,这就是我理解这个问题的方式)。

这是一个有 100 行的表格(这就是您的“100 卷”)。

SQL> create table test (id) as
  2  select level from dual connect by level <= 100;

Table created.

然后将

20
(即“20 个月的持续时间”)传递给
ntile
并获得结果 - 请参阅
grp
列,有 20 个组,每组有 5 行:

SQL> select id, ntile(20) over (order by id) grp
  2  from test
  3  order by id;

        ID        GRP
---------- ----------
         1          1
         2          1
         3          1
         4          1
         5          1
         6          2
         7          2
         8          2
         9          2
        10          2
        11          3
        12          3
        13          3
        14          3
        15          3
   <snip>
        91         19
        92         19
        93         19
        94         19
        95         19
        96         20
        97         20
        98         20
        99         20
       100         20

100 rows selected.

SQL>

[编辑,根据新信息]

您发布的示例表格:

SQL> with
  2  duration (product, duration) as
  3    (select 'A', 10 from dual union all
  4     select 'B', 6  from dual union all
  5     select 'C', 4  from dual
  6    ),
  7  cost (product, cost) as
  8    (select 'A', 100 from dual union all
  9     select 'B', 50  from dual union all
 10     select 'C', 40  from dual
 11    )

查询看起来像这样:

 12  select d.product,
 13         c.cost / d.duration as amount
 14  from duration d join cost c on c.product = d.product
 15    cross join table(cast(multiset(select level from dual
 16                                   connect by level <= d.duration
 17                                  ) as sys.odcinumberlist))
 18  order by d.product;

PRODUCT        AMOUNT
---------- ----------
A                  10
A                  10
A                  10
A                  10
A                  10
A                  10
A                  10
A                  10
A                  10
A                  10
B          8,33333333
B          8,33333333
B          8,33333333
B          8,33333333
B          8,33333333
B          8,33333333
C                  10
C                  10
C                  10
C                  10

20 rows selected.

SQL>
© www.soinside.com 2019 - 2024. All rights reserved.