使用 Common Table 表达式("WITH AS " 子句)的 DELETE 查询
DELETE query with Common Table Expression ("WITH AS " clause)
我正在尝试从我的 Oracle 数据中删除 41.6% 的旧行table(senstrig 是一种日期格式):
DELETE FROM
(WITH RS AS (SELECT * FROM OLD_WIFISIGN WHERE SENSID= 1 ORDER BY SENSTRIG ASC))
WHERE ROWNUM <= (SELECT COUNT (*)/ 2.4 FROM RS);
但它 returns 一个错误:
ORA-00928 missing SELECT
我已经尝试了几个版本,但都没有成功。
你能帮我看看我怎样才能让这个 "delete from" 可以运行吗?
将WITH
放在DELETE
之前:
WITH RS AS (SELECT * FROM OLD_WIFISIGN WHERE SENSID= 1 ORDER BY SENSTRIG ASC)
DELETE FROM OLD_WIFISIGN
WHERE ROWNUM <= (SELECT COUNT (*)/ 2.4 FROM RS);
还是有点奇怪,order by的目的是什么?
测试 table,1000 行,全部为 sensid = 1
:
create table old_wifisign (sensid, senstrig) as (
select 1, trunc(sysdate) - level
from dual connect by level <= 1000);
删除:
delete
from old_wifisign
where rowid in (
select rowid
from (
select rowid, row_number() over (order by senstrig) / count(1) over () rto
from old_wifisign
where sensid = 1 )
where rto <= .416)
结果:删除了最旧的 senstrig 的 416 行。请注意,此处仅将 sensid 1 纳入计算,如您的查询所示。
要删除 41.6% 的旧行,请先检查要删除的边界日期,然后再使用它。
解析函数PERCENT_RANK
给你最年轻的senstrig
你不想删除
with perc_rank as (
select SENSID, SENSTRIG,
PERCENT_RANK() OVER (ORDER BY senstrig) AS pr
from old_wifisign)
select max(SENSTRIG) from perc_rank
where pr < .416
比你简单的接受这个日期并执行 DELETE
delete from old_wifisign
where SENSTRIG <
(with perc_rank as (
select SENSID, SENSTRIG,
PERCENT_RANK() OVER (ORDER BY senstrig) AS pr
from old_wifisign)
select max(SENSTRIG) from perc_rank
where pr < .416
);
无论如何你应该小心考虑 ties - 关于 table 中一半行具有相同 senstrig
[=17 的情况=]
我正在尝试从我的 Oracle 数据中删除 41.6% 的旧行table(senstrig 是一种日期格式):
DELETE FROM
(WITH RS AS (SELECT * FROM OLD_WIFISIGN WHERE SENSID= 1 ORDER BY SENSTRIG ASC))
WHERE ROWNUM <= (SELECT COUNT (*)/ 2.4 FROM RS);
但它 returns 一个错误:
ORA-00928 missing SELECT
我已经尝试了几个版本,但都没有成功。
你能帮我看看我怎样才能让这个 "delete from" 可以运行吗?
将WITH
放在DELETE
之前:
WITH RS AS (SELECT * FROM OLD_WIFISIGN WHERE SENSID= 1 ORDER BY SENSTRIG ASC)
DELETE FROM OLD_WIFISIGN
WHERE ROWNUM <= (SELECT COUNT (*)/ 2.4 FROM RS);
还是有点奇怪,order by的目的是什么?
测试 table,1000 行,全部为 sensid = 1
:
create table old_wifisign (sensid, senstrig) as (
select 1, trunc(sysdate) - level
from dual connect by level <= 1000);
删除:
delete
from old_wifisign
where rowid in (
select rowid
from (
select rowid, row_number() over (order by senstrig) / count(1) over () rto
from old_wifisign
where sensid = 1 )
where rto <= .416)
结果:删除了最旧的 senstrig 的 416 行。请注意,此处仅将 sensid 1 纳入计算,如您的查询所示。
要删除 41.6% 的旧行,请先检查要删除的边界日期,然后再使用它。
解析函数PERCENT_RANK
给你最年轻的senstrig
你不想删除
with perc_rank as (
select SENSID, SENSTRIG,
PERCENT_RANK() OVER (ORDER BY senstrig) AS pr
from old_wifisign)
select max(SENSTRIG) from perc_rank
where pr < .416
比你简单的接受这个日期并执行 DELETE
delete from old_wifisign
where SENSTRIG <
(with perc_rank as (
select SENSID, SENSTRIG,
PERCENT_RANK() OVER (ORDER BY senstrig) AS pr
from old_wifisign)
select max(SENSTRIG) from perc_rank
where pr < .416
);
无论如何你应该小心考虑 ties - 关于 table 中一半行具有相同 senstrig
[=17 的情况=]