我有下面的表(我的输入将只是列NIF,文件和FILESIZE)。
我想使用以下规则获取列PARTITION和SUBPARTITION:
- PARTITION应以1开始,每次调整SUBPARTITION达到8时递增1。
1.单个NIF不能位于两个不同的PARTITION中。(这实际上是最严格的条件)。
1.每次FILESIZE中的运行总数达到10时,SUBPARTITION必须递增1。当SUBPARTITION递增1时,必须重置该运行总计。
数据来源:
NIF FILE FILESIZE PARTITION SUBPARTITION
----------------------------------------------
A C1 1 1 1
A C2 1 1 1
A C3 2 1 1
A C4 1 1 1
B C5 5 1 2
B C6 1 1 2
C C7 2 1 2
C C8 1 1 2
D C9 4 1 3
D C10 5 1 3
D C11 1 1 3
D C12 2 1 4
D C13 3 1 4
D C14 4 1 4
D C15 5 1 5
E C16 3 1 6
E C17 2 1 6
E C18 3 1 6
E C19 4 1 7
F C20 6 2 1
F C20 2 2 1
字符串
它不需要是一个单一的查询,做一个PSLQL游标也可以。
注意:这是创建输入表的代码。
DROP TABLE my_table;
-- Create the table
CREATE TABLE my_table (
NIF VARCHAR2(10),
FILE_ VARCHAR2(10),
FILESIZE NUMBER
);
-- Insert the input data
INSERT INTO my_table (NIF, FILE_, FILESIZE)
SELECT 'A', 'C1', 1 FROM DUAL UNION ALL
SELECT 'A', 'C2', 1 FROM DUAL UNION ALL
SELECT 'A', 'C3', 2 FROM DUAL UNION ALL
SELECT 'A', 'C4', 1 FROM DUAL UNION ALL
SELECT 'B', 'C5', 5 FROM DUAL UNION ALL
SELECT 'B', 'C6', 1 FROM DUAL UNION ALL
SELECT 'C', 'C7', 2 FROM DUAL UNION ALL
SELECT 'C', 'C8', 1 FROM DUAL UNION ALL
SELECT 'D', 'C9', 4 FROM DUAL UNION ALL
SELECT 'D', 'C10', 5 FROM DUAL UNION ALL
SELECT 'D', 'C11', 1 FROM DUAL UNION ALL
SELECT 'D', 'C12', 2 FROM DUAL UNION ALL
SELECT 'D', 'C13', 3 FROM DUAL UNION ALL
SELECT 'D', 'C14', 4 FROM DUAL UNION ALL
SELECT 'D', 'C15', 5 FROM DUAL UNION ALL
SELECT 'E', 'C16', 3 FROM DUAL UNION ALL
SELECT 'E', 'C17', 2 FROM DUAL UNION ALL
SELECT 'E', 'C18', 3 FROM DUAL UNION ALL
SELECT 'E', 'C19', 4 FROM DUAL UNION ALL
SELECT 'F', 'C20', 6 FROM DUAL UNION ALL
SELECT 'F', 'C21', 2 FROM DUAL;
COMMIT;
型
3条答案
按热度按时间vq8itlhq1#
在Oracle 12中,您可以使用分析函数和
MATCH_RECOGNIZE
的组合来执行逐行处理:字符串
在第一匹配中,对于子分区,模式:
same_nif* nif
将从当前行匹配到当前NIF
分区的末尾,并通过检查当前大小加上下一个NIF
分区的总大小是否在限制范围内来确保下一个NIF
分区也将完全包含在匹配中;()*
中允许匹配零次或多次(尽可能多);same_nif* end_nif
允许匹配部分匹配具有相同nif
值的一组行(例如文件C9、C10和C11,它们与C12、C13和C14具有相同的nif
),但由于它们的文件大小总计超过限制,因此将处于不同的组中。如果没有不同的结束条件,您可能会将C1到C5分组,或者无法拆分D
nif
值。在第二匹配中,对于分区,
nif
值需要在同一匹配中保持在一起(而对于子分区,nif
值可以跨越多个匹配),除此之外,唯一需要的检查是在一个组中存在不超过7个子分区。对于样本数据(添加了一个
CTO
列和一个额外的nif
组G
,该组太大,无法与前一个nif
组F
合并在同一个分区中):型
输出:
| NIF|文件_|分区|细分|总尺寸| TOTAL_SIZE |
| --|--|--|--|--| ------------ |
| 一个|C1|一个|一个|一个| 1 |
| 一个|C2|一个|一个|二个| 2 |
| 一个|C3|一个|一个|四个| 4 |
| 一个|C4|一个|一个|五个| 5 |
| B级|C5|一个|二个|五个| 5 |
| B级|C6|一个|二个|六个| 6 |
| C类|C7|一个|二个|八个| 8 |
| C类|C8|一个|二个|九个| 9 |
| D级|C9|一个|三个|四个| 4 |
| D级|C10|一个|三个|九个| 9 |
| D级|C11|一个|三个|十个| 10 |
| D级|C12|一个|四个|二个| 2 |
| D级|C13|一个|四个|五个| 5 |
| D级|C14|一个|四个|九个| 9 |
| D级|C15|一个|五个|五个| 5 |
| E级|C16|一个|六个|三个| 3 |
| E级|C17|一个|六个|五个| 5 |
| E级|C18|一个|六个|八个| 8 |
| E级|C19|一个|七个|四个| 4 |
| F级|C20|二个|一个|六个| 6 |
| F级|C21|二个|一个|八个| 8 |
| G级|C22|三个|一个|十个| 10 |
| G级|C23|三个|二个|十个| 10 |
| G级|C24|三个|三个|十个| 10 |
| G级|C25|三个|四个|十个| 10 |
| G级|C26|三个|五个|十个| 10 |
| G级|C27|三个|六个|十个| 10 |
| G级|C28|三个|七个|十个| 10 |
fiddle
eoigrqb62#
您可以创建一个temporary table或一个真实的的Yable,字段为(NIF,FILE,FILESIZE,PARTITION,SUBPARTITION)。你也可以给它添加一个id,但是为了这个答案的目的,我只描述绝对最小值。
您可以将PARTITION和SUBPARTITION设置为可空,并通过以下命令插入行
字符串
并实现一个before insert trigger,它将找到
max(PARTITION)
,以找出当前分区是什么,以及该分区的max(SUBPARTITION)
沿着该分区中的sum(FILESIZE)
。类似于(这是一个不可知查询,您需要保存字段into
局部变量)型
从这里开始,在触发器中,您可以看到要插入的记录的
storage_use
+实际FILESIZE
是否大于10。如果没有,那么将新记录的PARTITION
和SUBPARTITION
设置为查询中找到的那些。如果不是,那么只要SUBPARTITION
小于或等于8,就可以递增SUBPARTITION
。如果SUBPARTITION
是8,并且storage_use
不允许您将新记录放入其中,则将PARTITION + 1
和SUBPARTITION + 1
分别存储为PARTITION
和SUBPARTITION
。gg0vcinb3#
也可以使用MODEL子句:
字符串