我的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
答案 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)
我会给你一个方法:
测试案例
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>
因此,对于分割后值不是整数的组,您也可以考虑它们。