删除语句不适用于oracle中的查询
Delete statement not working on query in oracle
我有一个tableBK_178_ABC
。我只想在满足某些条件时在此 table 上执行删除语句:
我对此 table 的总计数是:
select count(*) from BK_178_ABC; ==>22024727
我有下面这个条件,如果它满足那么我需要从这个BK_178_ABC中删除table.So,我首先计算了总行数是多少deleted.So ,我试过下面的语句。
SELECT Count(*)
FROM
BK_178_ABC a
LEFT JOIN
(SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr
ON
SubStr (a.PS_UNIQUE_ID,-8) = gr.SOURCEID
LEFT JOIN
(SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr2
ON
a.GROUP_NBR = gr2.SOURCEID
WHERE EXISTS
(
SELECT 1 FROM droptable drp
WHERE
COALESCE(gr.ROLLUPGROUPID, gr2.ROLLUPGROUPID, SubStr(a.ps_unique_id,-8))=drp.groupid
);
所以,要删除的计数是:2902563.
我尝试了两个删除语句,但是它们都给了我错误的 count.Since,我的预期计数是 2902563,但我没有得到正确的结果。
DELETE FROM bk_178_abc WHERE EXISTS (SELECT 1
FROM bk_178_abc a
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr
ON Substr (a.ps_unique_id, -8) = gr.sourceid
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr2
ON a.group_nbr = gr2.sourceid
WHERE EXISTS (SELECT 1
FROM droptable drp
WHERE COALESCE(gr.rollupgroupid,
gr2.rollupgroupid,
Substr(a.ps_unique_id, -8)) = drp.groupid))
;
它清空了整个 table,因为我看到删除的总数是:22024727
所以,我再次重构了上面的代码,尝试了另一个删除语句:
DECLARE
begin
DELETE FROM BK_178_ABC a WHERE EXISTS (SELECT 1 FROM (SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr,
xyz gr2,
droptable drp WHERE SubStr (a.PS_UNIQUE_ID,-8) = gr.SOURCEID AND a.GROUP_NBR = gr.SOURCEID
AND COALESCE(gr.ROLLUPGROUPID, gr2.ROLLUPGROUPID, SubStr(a.ps_unique_id,-8))=drp.groupid );
Dbms_Output.put_line(SQL%ROWCOUNT);
END;
我看到行数是 零。我的 sql 语句有什么问题?
您可以使用 IN 如下:
DELETE FROM bk_178_abc WHERE rowid in (SELECT a.rowid
FROM bk_178_abc a
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr
ON Substr (a.ps_unique_id, -8) = gr.sourceid
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr2
ON a.group_nbr = gr2.sourceid
WHERE EXISTS (SELECT 1
FROM droptable drp
WHERE COALESCE(gr.rollupgroupid,
gr2.rollupgroupid,
Substr(a.ps_unique_id, -8)) = drp.groupid))
;
您可能想要使用性能更好的不同技术。在您的情况下,您可以使用 CTAS/TRUNCATE/BULK COLLECT,因为您想要删除 table(2902563 of 22024727)中超过 10% 的行。根据我的经验,当你想要消除超过 10% 的行或你的 table,并且数字超过一百万时,这种技术会更快。但是,请注意 INSERT APPEND 将锁定 table,因为它是直接路径操作。
此技术的近似值是
alter session enable parallel dml ;
alter session enable parallel ddl ;
alter session force parallel query ;
create table res_bk_178_abc parallel compress
for
select * FROM bk_178_abc WHERE rowid in (SELECT a.rowid
FROM bk_178_abc a
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr
ON Substr (a.ps_unique_id, -8) = gr.sourceid
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr2
ON a.group_nbr = gr2.sourceid
WHERE EXISTS (SELECT 1
FROM droptable drp
WHERE COALESCE(gr.rollupgroupid,
gr2.rollupgroupid,
Substr(a.ps_unique_id, -8)) = drp.groupid)) ;
truncate table bk_178_abc reuse storage;
insert /*+append parallel(a) */ into bk_178_abc a select /*+parallel(b) */ * from res_bk_178_abc b;
commit;
drop table res_bk_178_abc purge;
基本上,在这种情况下,我没有删除近 300 万行或 22 ,这很昂贵,我创建了一个 table 包含我想保留的行,截断原始行,然后插入回使用具有并行启用的直接路径操作的数据。
在 create table as select (CTAS) 中,您可以使用提示来强制并行查询,但因为我不知道您的数据模型以及您在那些 tables,我没有碰那部分。 @Tajesh 正确地包含了 rowid 引用,以仅获取必须删除的行数。
此致
我有一个tableBK_178_ABC
。我只想在满足某些条件时在此 table 上执行删除语句:
我对此 table 的总计数是:
select count(*) from BK_178_ABC; ==>22024727
我有下面这个条件,如果它满足那么我需要从这个BK_178_ABC中删除table.So,我首先计算了总行数是多少deleted.So ,我试过下面的语句。
SELECT Count(*)
FROM
BK_178_ABC a
LEFT JOIN
(SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr
ON
SubStr (a.PS_UNIQUE_ID,-8) = gr.SOURCEID
LEFT JOIN
(SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr2
ON
a.GROUP_NBR = gr2.SOURCEID
WHERE EXISTS
(
SELECT 1 FROM droptable drp
WHERE
COALESCE(gr.ROLLUPGROUPID, gr2.ROLLUPGROUPID, SubStr(a.ps_unique_id,-8))=drp.groupid
);
所以,要删除的计数是:2902563.
我尝试了两个删除语句,但是它们都给了我错误的 count.Since,我的预期计数是 2902563,但我没有得到正确的结果。
DELETE FROM bk_178_abc WHERE EXISTS (SELECT 1
FROM bk_178_abc a
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr
ON Substr (a.ps_unique_id, -8) = gr.sourceid
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr2
ON a.group_nbr = gr2.sourceid
WHERE EXISTS (SELECT 1
FROM droptable drp
WHERE COALESCE(gr.rollupgroupid,
gr2.rollupgroupid,
Substr(a.ps_unique_id, -8)) = drp.groupid))
;
它清空了整个 table,因为我看到删除的总数是:22024727
所以,我再次重构了上面的代码,尝试了另一个删除语句:
DECLARE
begin
DELETE FROM BK_178_ABC a WHERE EXISTS (SELECT 1 FROM (SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr,
xyz gr2,
droptable drp WHERE SubStr (a.PS_UNIQUE_ID,-8) = gr.SOURCEID AND a.GROUP_NBR = gr.SOURCEID
AND COALESCE(gr.ROLLUPGROUPID, gr2.ROLLUPGROUPID, SubStr(a.ps_unique_id,-8))=drp.groupid );
Dbms_Output.put_line(SQL%ROWCOUNT);
END;
我看到行数是 零。我的 sql 语句有什么问题?
您可以使用 IN 如下:
DELETE FROM bk_178_abc WHERE rowid in (SELECT a.rowid
FROM bk_178_abc a
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr
ON Substr (a.ps_unique_id, -8) = gr.sourceid
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr2
ON a.group_nbr = gr2.sourceid
WHERE EXISTS (SELECT 1
FROM droptable drp
WHERE COALESCE(gr.rollupgroupid,
gr2.rollupgroupid,
Substr(a.ps_unique_id, -8)) = drp.groupid))
;
您可能想要使用性能更好的不同技术。在您的情况下,您可以使用 CTAS/TRUNCATE/BULK COLLECT,因为您想要删除 table(2902563 of 22024727)中超过 10% 的行。根据我的经验,当你想要消除超过 10% 的行或你的 table,并且数字超过一百万时,这种技术会更快。但是,请注意 INSERT APPEND 将锁定 table,因为它是直接路径操作。
此技术的近似值是
alter session enable parallel dml ;
alter session enable parallel ddl ;
alter session force parallel query ;
create table res_bk_178_abc parallel compress
for
select * FROM bk_178_abc WHERE rowid in (SELECT a.rowid
FROM bk_178_abc a
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr
ON Substr (a.ps_unique_id, -8) = gr.sourceid
LEFT JOIN (SELECT *
FROM xyz
WHERE Upper(type) = 'MOOV'
AND Upper(buyer) = 'KERA') gr2
ON a.group_nbr = gr2.sourceid
WHERE EXISTS (SELECT 1
FROM droptable drp
WHERE COALESCE(gr.rollupgroupid,
gr2.rollupgroupid,
Substr(a.ps_unique_id, -8)) = drp.groupid)) ;
truncate table bk_178_abc reuse storage;
insert /*+append parallel(a) */ into bk_178_abc a select /*+parallel(b) */ * from res_bk_178_abc b;
commit;
drop table res_bk_178_abc purge;
基本上,在这种情况下,我没有删除近 300 万行或 22 ,这很昂贵,我创建了一个 table 包含我想保留的行,截断原始行,然后插入回使用具有并行启用的直接路径操作的数据。
在 create table as select (CTAS) 中,您可以使用提示来强制并行查询,但因为我不知道您的数据模型以及您在那些 tables,我没有碰那部分。 @Tajesh 正确地包含了 rowid 引用,以仅获取必须删除的行数。
此致