简体   繁体   English

如何使用 rowid 和 rownum 在合并语句中添加两个条件

[英]How to add two conditions in merge statement using rowid and rownum

CREATE SEQUENCE e_demo2_tab_sq;

CREATE TABLE e_demo2_tab 
(
    tab_id   NUMBER(10) DEFAULT e_demo2_tab_sq.nextval NOT NULL,
    e_id     NUMBER(10),
    e_uuid   NUMBER(10),
    seq_cnt  NUMBER(10)
);

INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 13, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 13, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 16, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 15, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 14, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 14, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 15, null);
INSERT INTO e_demo2_tab VALUES(e_demo2_tab_sq.nextval, 11, 16, null);

Query to load the sequence for e_uuid 13 & 15查询以加载e_uuid 13 和 15 的序列

merge into e_demo2_tab a
      using (select
               rowid rid,
               row_number() over (partition by e_id, e_uuid order by rowid) rn
             from e_demo2_tab where e_uuid in(13,15)
            ) x
    on (a.rowid = x.rid)
    when matched then update set a.seq_cnt = x.rn;

Then I want to merge into the same table for e_uuid 14 & 16 For 14: It should check e_uuid = 13 and maximum seq_cnt .然后我想将e_uuid 14 & 16 合并到同一个表中 For 14: 它应该检查e_uuid = 13 和 maximum seq_cnt Here(after executing my merge statement) maximum seq_cnt is 2 then the seq_cnt for 14 will come as 3 & 4. And if there are any null values then need to give by default 1 in seq_cnt这里(执行我的合并语句后)最大seq_cnt是 2 那么 14 的seq_cnt将是 3 和 4。如果有任何 null 值,则需要在seq_cnt中默认给出 1

For 16: It should check e_uuid = 15 and maximum seq_cnt .对于 16:它应该检查e_uuid = 15 和 maximum seq_cnt Here(after executing my merge statement) maximum seq_cnt is 2 then the seq_cnt for 16 will come as 3 & 4.这里(执行我的合并语句后)最大seq_cnt是 2 那么 16 的seq_cnt将是 3 和 4。

Output after executing the merge statement given above Output 执行上面给出的合并语句后

+--------+------+--------+---------+
| TAB_ID | E_ID | E_UUID | SEQ_CNT |
+--------+------+--------+---------+
|      1 | 11   |     13 | 1       |
|      2 | 11   |     13 | 2       |
|      3 | 11   |     16 | null    |
|      4 | 11`  |     15 | 1       |
|      5 | 11   |     14 | null    |
|      6 | 11   |     14 | null    |
|      7 | 11   |     15 | 2       |
|      8 | 11   |     16 | null    |
+--------+------+--------+---------+

Expected Output:预计 Output:

+--------+------+--------+---------+
| TAB_ID | E_ID | E_UUID | SEQ_CNT |
+--------+------+--------+---------+
|      1 | 11   |     13 |       1 |
|      2 | 11   |     13 |       2 |
|      3 | 11   |     16 |       3 |
|      4 | 11`  |     15 |       1 |
|      5 | 11   |     14 |       3 |
|      6 | 11   |     14 |       4 |
|      7 | 11   |     15 |       2 |
|      8 | 11   |     16 |       4 |
+--------+------+--------+---------+

If you're wanting to group an odd and a consecutive even e_uuid together, you could always change the partition by clause to group on ceil(e_uuid/2) , like so:如果您想将一个奇数和一个连续的偶数 e_uuid 组合在一起,您总是可以将partition by子句更改为 group on ceil(e_uuid/2) ,如下所示:

merge into e_demo2_tab a
      using (select
               rowid rid,
               row_number() over (partition by e_id, ceil(e_uuid/2) order by e_uuid, rowid) rn
             from e_demo2_tab) x
    on (a.rowid = x.rid)
    when matched then update set a.seq_cnt = x.rn;

db<>fiddle 数据库<>小提琴

This works because 13/2 = 6.5, and the ceiling value of 6.5 = 7. 14/2 = 7, the ceiling value of which is also 7, since it's already an integer. That makes 13 and 14 grouped together - same logic applies to 15 and 16 - the ceiling of them divided by two comes to 8 for both values.这是有效的,因为 13/2 = 6.5,上限值为 6.5 = 7。14/2 = 7,其上限值也是 7,因为它已经是 integer。这使得 13 和 14 组合在一起 - 适用相同的逻辑到 15 和 16 - 两个值的上限都为 8。

So that explains the logic behind grouping them together (13 is odd, and 14 is the next consecutive even number).这样就解释了将它们组合在一起背后的逻辑(13 是奇数,14 是下一个连续的偶数)。

The rows are then ordered by e_uuid, and then rowid to get the ordering you were after.然后按 e_uuid 和 rowid 对行进行排序以获得您之后的排序。

If you are only ever concerned about the 13, 14, 15, and 16 e_uuids, you might want to have a filter in your x subquery of where e_uuid in (13, 14, 15, 16) , depending on if there are other values of e_uuid in your table.如果您只关心 13、14、15 和 16 个 e_uuids,您可能希望在where e_uuid in (13, 14, 15, 16)的 x 子查询中有一个过滤器,具体取决于是否有其他值表中的 e_uuid。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM