如何在Oracle中根据列存在和分组在两个表之间选择值

6ioyuze2  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(164)

我尝试根据两个表之间的几个列中的值的存在和匹配,从两个表中的一个表中选择一个值。它可以被看作是tbl_b是tbl_a的覆盖表,当某些列匹配(ndx 1,ndx 2)并且tbl_b val列中存在值时。我正在寻找一种有效的方法来获得正确的值(参见下面的规则和预期结果)。我很难正确地进行分组以获得预期的结果(尝试小提琴)。
我现在用的是Oracle 19 c。

CREATE TABLE tbl_a (id number, ndx1 number, ndx2 number, val number);
CREATE TABLE tbl_b (id number, ndx1 number, ndx2 number, val number);
INSERT INTO tbl_a VALUES (100, 1, 1, 2000);
INSERT INTO tbl_a VALUES (200, 1, 1, 4000);
INSERT INTO tbl_a VALUES (300, 1, 1, 6000);
INSERT INTO tbl_a VALUES (400, 1, 1, 8000);
INSERT INTO tbl_b VALUES (100, 1, 1, null);
INSERT INTO tbl_b VALUES (200, 1, 1, 10000);
INSERT INTO tbl_b VALUES (300, 1, 2, 40000);
select *
from tbl_a;

| ID| NDX1| NDX2|瓦尔|
| --|--|--|--|
| 100 | 1 | 1 | 2000 |
| 200 | 1 | 1 | 4000 |
| 300 | 1 | 1 | 6000 |
| 400 | 1 | 1 | 8000 |

select *
from tbl_b;

| ID| NDX1| NDX2|瓦尔|
| --|--|--|--|
| 100 | 1 | 1 |* 空 *|
| 200 | 1 | 1 | 10000 |
| 300 | 1 | 2 | 40000 |
这些是我试图实现的规则,以获得适当的值。我把它当作tbl_b是tbl_a的覆盖表(当存在匹配的ndx 1和ndx 2值并且存在tbl_b.val时)。
1.如果ndx 1和ndx 2存在并且在两个表中匹配,则使用b.瓦尔(如果存在),否则使用a.瓦尔
如果a.ndx1=b.ndx1且a.ndx2=b.ndx2,则nvl(b.瓦尔,a.瓦尔)
1.如果ndx 1存在且在两个表中匹配,但ndx 2不在tbl_b中,则取.瓦尔
例如)如果a.ndx1=b.ndx1且b.ndx2为空,则取a.瓦尔
1.如果ndx 1存在且在两个表中匹配,但ndx 2不在tbl_a中,则取b。瓦尔
例如)如果a.ndx1=b.ndx1且a.ndx2为空,则取b.瓦尔
1.如果a.ndx1不存在,则不考虑b.ndx1(tbl_a是驱动程序)
预期结果表:
| ID| NDX1| NDX2|瓦尔|
| --|--|--|--|
| 100 | 1 | 1 | 2000 |
| 200 | 1 | 1 | 10000 |
| 300 | 1 | 1 | 6000 |
| 300 | 1 | 2 | 40000 |
| 400 | 1 | 1 | 8000 |
fiddle

yftpprvb

yftpprvb1#

使用FULL OUTER JOIN,然后COALESCE,使tbl_b优先于tbl_a

SELECT COALESCE(b.id, a.id) AS id,
       COALESCE(b.ndx1, a.ndx1) AS ndx1,
       COALESCE(b.ndx2, a.ndx2) AS ndx2,
       COALESCE(b.val, a.val) AS val
FROM   tbl_a a
       FULL OUTER JOIN tbl_b b
       ON     a.id   = b.id
          AND a.ndx1 = b.ndx1
          AND a.ndx2 = b.ndx2
ORDER BY id, ndx1, ndx2

对于样本数据,其输出:
| ID| NDX1| NDX2|瓦尔|
| --|--|--|--|
| 100 | 1 | 1 | 2000 |
| 200 | 1 | 1 | 10000 |
| 300 | 1 | 1 | 6000 |
| 300 | 1 | 2 | 40000 |
| 400 | 1 | 1 | 8000 |
fiddle

相关问题