我遇到了一种奇怪的情况,我有一个主表,其中没有标志来识别或标记要删除的记录,所以我必须依赖 rowid。表A看起来像
客户_编号 | 身份代码 | 身份号码 |
---|---|---|
1234 | 护照 | ABCDEFGH |
1234 | 护照 | ABCDEFGH |
1234 | 阿达尔 | 1234 5678 9123 |
5678 | 护照 | ABCDEFGH |
现在,当我在 Oracle 表单上搜索详细信息时,我使用 ABCDEFGH,它会向我显示所有具有匹配记录的客户。因此输出将与上面类似,但带有附加列(这是我的第二个表 B)作为
客户_编号 | 身份代码 | 身份号码 | 维持 | 删除 | n_merge_seq |
---|---|---|---|---|---|
1234 | 护照 | ABCDEFGH | 是的 | 没有 | 1 |
1234 | 护照 | ABCDEFGH | 没有 | 是的 | 1 |
1234 | 阿达尔 | 1234 5678 9123 | 是的 | 没有 | 1 |
5678 | 护照 | ABCDEFGH | 没有 | 是的 | 1 |
还有第三个表 C,仅存储客户编号和标志,如下所示。只能维护一个客户。
客户_编号 | 维护 | 删除 | n_merge_seq |
---|---|---|---|
1234 | 是 | N | 1 |
5678 | N | 是 | 1 |
我无法从 TableB 中删除数据,因为这是审核表,同样适用于 TableC。
我使用 min(rowid) 只保留每个 customer_no||身份代码||IdentityNumber 的最小 rowid 记录,其中 B.maintain = Yes 且 C.maintain = Y
cursor cr_save_Y is
SELECT y.n_cust_ref_no,y.v_iden_code,y.v_iden_no,MIN(z.rowid) row_idn
FROM TableC x,
TableB y,
TableA z
WHERE x.customer_no = y.customer_no
AND x.n_merge_seq = y.n_merge_seq
AND y.identitycode = z.identitycode
AND y.identitynumber = z.identitynumber
AND y.customer_no = z.customer_no
AND NVL(y.v_maintain,'Y')='Y' ---iden no to keep
AND x.n_merge_cust_seq = 1
GROUP BY y.customer_no,
y.identitycode,
y.identitynumber ;
然后我像下面一样循环播放
for i in cr_save_Y
loop
delete from TableA
where customer_no = i.customer_no
and identitycode = i.identitycode
and identityNumber = i.identityNumber
and rowid <> i.row_idn;
end loop;
到这里,就可以了,因为如果 row_id 不匹配,我的记录就会被保存。问题出现在下一行代码中。在下面的代码中,我将从 TableA 中删除数据,其中如果记录是维护或删除 = 'Y',则获取记录并删除确切的记录。
delete from TableA
where customer_no||identitycode||identitynumber in (select y.customer_no||y.identitycode||y.identitynumber
from TableC x,TableB y
where x.customer_no=y.customer_no
and x.n_merge_seq=y.n_merge_seq and nvl(y.maintain,'N')='N' and x.n_merge_seq=1
and (x.maintain = 'Y' or x.remove='Y');
但是由于我无法从 TableB 中删除数据,它仍然有记录,其中 1234||passport||ABCDEFGH 将根据上述查询获取,因为 tableB.maintain = N 和 TableC.maintain = Y。因此该记录将匹配到我的 tableA 记录 1234||passport||ABCDEFGH 这样,两条记录现在都被删除了,我什么都没有了。
假设,我编写如下代码
delete from TableA
where customer_no||identitycode||identitynumber in (select y.customer_no||y.identitycode||y.identitynumber
from TableC x,TableB y
where x.customer_no=y.customer_no
and x.n_merge_seq=y.n_merge_seq and nvl(y.maintain,'N')='N' and x.n_merge_seq=1
and (x.remove='Y');
那么,下面的情况也无法解决目的
客户_编号 | 身份代码 | 身份号码 |
---|---|---|
1234 | 护照 | ABCDEFGH |
1234 | 阿达尔 | 1234 5678 9123 |
5678 | 护照 | ABCDEFGH |
客户_编号 | 身份代码 | 身份号码 | 维持 | 删除 | n_merge_seq |
---|---|---|---|---|---|
1234 | 护照 | ABCDEFGH | 是的 | 没有 | 1 |
1234 | 阿达尔 | 1234 5678 9123 | 没有 | 是的 | 1 |
5678 | 护照 | ABCDEFGH | 没有 | 是的 | 1 |
这样就只会取出5678||passport||ABCDEFGH并删除它,但我的另一条记录1234||adhar||123456789123不会被删除。
有没有办法同时满足这两种场景?上面的sql查询失败,因为如果我同时选择维护和删除,那么我担心两条记录都会被删除。
我需要如下的输出
场景一:
客户_编号 | 身份代码 | 身份号码 |
---|---|---|
1234 | 护照 | ABCDEFGH |
1234 | 阿达尔 | 1234 5678 9123 |
场景2:
客户_编号 | 身份代码 | 身份号码 |
---|---|---|
1234 | 护照 | ABCDEFGH |
您是否考虑过从表 A 中删除重复的行。表中没有 2 个或更多相同的行。这只会带来问题。也许这里最好的做法是将表 A 减少为不同的行 - 删除重复的行:
Delete From tbl_a
Where rowid NOT IN ( Select Min( ROWID )
From tbl_a
Group By Customer_No, IdentityCode, IdentityNumber
);