根据值拆分行

时间:2015-03-03 11:51:02

标签: sql oracle

我的Oracle数据库中有以下表格

TopCode BottomCode  Totalpeep
A   ABC123      100
B   BED456           45

我想要一个能够根据Totalpeep / 20分割行的查询,例如A组有5组,B组有3组,即使Totalpeep小于20组,也必须有一组

TopCode  BottomCode  Grp
A        ABC123      A1
A        ABC123      A2
A        ABC123      A3
A        ABC123      A4
A        ABC123      A5
B        BED456      B1
B        BED456      B2
B        BED456      B3

2 个答案:

答案 0 :(得分:2)

使用connect方式轻松实现:

with sample_data (TopCode, BottomCode, Totalpeep) as (select 'A', 'ABC123', 100 from dual union all
                                                      select 'B', 'BED456', 45 from dual)
select topcode,
       bottomcode,
       topcode||level grp
from   sample_data
connect by prior topcode = topcode
           and prior dbms_random.value is not null
           and level <= ceil(totalpeep/20);

TOPCODE BOTTOMCODE GRP                                      
------- ---------- ----
A       ABC123     A1
A       ABC123     A2
A       ABC123     A3
A       ABC123     A4
A       ABC123     A5
B       BED456     B1
B       BED456     B2
B       BED456     B3

答案 1 :(得分:0)

我会给你一个方法:

  1. 划分列值会提供您需要拆分的行数
  2. 然后进一步除以该计数将其分为相等数量的桶。其余的是 ROW GENERATOR 方法。
  3. 测试案例

    SQL> CREATE TABLE t(
      2  topcode VARCHAR2(10),
      3  totalpeep NUMBER);
    
    Table created.
    
    SQL>
    SQL> INSERT INTO t VALUES('A', 100);
    
    1 row created.
    
    SQL> INSERT INTO t VALUES('B', 45);
    
    1 row created.
    
    SQL>
    SQL> SELECT * FROM t;
    
    TOPCODE     TOTALPEEP
    ---------- ----------
    A                 100
    B                  45
    
    SQL>
    

    因此,SQL根据计数创建相同数量的桶:

    SQL> WITH DATA AS
      2    ( SELECT t.*, t.totalpeep/20 wt_bucket  FROM t )
      3  SELECT topcode, topcode||level
      4  FROM DATA
      5    CONNECT BY LEVEL          <= wt_bucket
      6  AND PRIOR topcode            = topcode
      7  AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
      8  /
    
    TOPCODE    TOPCODE||LEVEL
    ---------- --------------------------------------------
    A          A1
    A          A2
    A          A3
    A          A4
    A          A5
    B          B1
    B          B2
    
    7 rows selected.
    
    SQL>
    
      

    即使Totalpeep小于20,也必须有一组

    在这种情况下,还应考虑未使用的剩余铲斗:

    SQL> WITH DATA AS
      2    ( SELECT t.*, t.totalpeep/20 wt_bucket  FROM t )
      3  SELECT topcode, topcode||level
      4  FROM DATA
      5    CONNECT BY LEVEL          <= ceil(wt_bucket)
      6  AND PRIOR topcode            = topcode
      7  AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
      8  /
    
    TOPCODE    TOPCODE||LEVEL
    ---------- --------------------------------------------
    A          A1
    A          A2
    A          A3
    A          A4
    A          A5
    B          B1
    B          B2
    B          B3
    
    8 rows selected.
    
    SQL>
    

    因此,对于分割后值不是整数的组,您也可以考虑它们。